线程不能在ptc线程中并发工作
所以我有一个快速排序算法,我想在两个不同的线程中运行,其思想是让数组的两个独立部分同时被排序(分区的快速排序性质不应该是一个问题) 我的代码如下:线程不能在ptc线程中并发工作,c,multithreading,pthreads,C,Multithreading,Pthreads,所以我有一个快速排序算法,我想在两个不同的线程中运行,其思想是让数组的两个独立部分同时被排序(分区的快速排序性质不应该是一个问题) 我的代码如下: #include <stdio.h> #include <stdlib.h> #include <pthread.h> void troca (int *v, int i, int j); int partition (int *v, int ini, int fim); void quicksort (int
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void troca (int *v, int i, int j);
int partition (int *v, int ini, int fim);
void quicksort (int *v, int ini, int fim, int size);
typedef struct {
int ini, mid, fim;
} thread_arg;
int size;
int *v;
void *thread_func(void* arg){
thread_arg *a = arg;
quicksort(v, a->ini, a->mid, a->fim);
printf("done in\n");
return NULL;
}
int main()
{
// initializations
scanf("%d", &size);
v = malloc(size * sizeof(int));
// read array
for (int i = 0; i < size; ++i)
scanf("%d", &v[i]);
// arguments
thread_arg argument1, argument2;
int mid = partition(v, 0, size-1);
argument1.ini = 0;
argument1.mid = mid-1;
argument1.fim = size;
argument2.ini = mid;
argument2.mid = size-1;
argument2.fim = size;
pthread_t thread1, thread2;
// thread and execution
pthread_create(&thread1, NULL, thread_func, &argument1);
printf("done out 1\n");
pthread_create(&thread2, NULL, thread_func, &argument2);
printf("done out 2\n");
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
free(v);
return 0;
}
void quicksort (int *v, int ini, int fim, int size){
if (ini >= fim)
return;
int meio = partition(v, ini, fim);
quicksort(v, ini, meio-1, size);
quicksort(v, meio+1, fim, size);
}
int partition (int *v, int ini, int fim){
int i = ini-1, j = ini;
troca(v, (ini+fim)/2, fim);
int pivo = v[fim];
for (; j < fim; ++j)
{
if (v[j] <= pivo)
{
i++;
troca(v, i, j);
}
}
troca(v, i+1, fim);
return i+1; //indice do pivo;
}
void troca (int *v, int i, int j){
int aux = v[i];
v[i] = v[j];
v[j] = aux;
return;
}
// thread and execution
pthread_create(&thread1, NULL, thread_func, &argument1);
printf("done out 1 (%d)\n", argument1.mid - argument1.ini + 1);
pthread_create(&thread2, NULL, thread_func, &argument2);
printf("done out 2 (%d)\n", argument2.mid - argument2.ini + 1);
但前3行显示大约需要25秒,最后一行显示大约需要25秒,这表示第二个线程正在等待第一个线程运行
在htop
控制台中,在某些情况下,两个程序似乎同时运行(这是因为该程序运行速度比我的正常程序快一点)
最后,我明白,同时处理此类数据是不安全的,但在这个排序示例中,它应该是好的。线程创建是不公平的:线程1在线程2之前创建。此外,当创建线程#1时,它可能会运行并抢占主线程,主线程可能会等待它返回CPU以创建和启动线程#2。但是,在默认SCHED_OTHER策略下运行的线程具有不可预测的行为 要增加一些可预测性:
- 创建线程后,使线程同时启动。使用屏障同时触发所有线程的“go”。比照
#包括
#包括
#包括
void troca(int*v,int i,int j);
内部分区(内部*v、内部ini、内部fim);
无效快速排序(int*v、int-ini、int-fim、int-size);
pthread_barrier_t barrier;
类型定义结构{
int-id;
int ini、mid、fim;
}线程参数;
整数大小;
int*v;
void*thread_func(void*arg){
线程_arg*a=arg;
pthread_barrier_wait(&barrier);
快速排序(v,a->ini,a->mid,a->fim);
printf(“在%d\n中完成”,a->id);
返回NULL;
}
int main()
{
//初始化
scanf(“%d”,大小(&S);
v=malloc(大小*尺寸(int));
//读取数组
对于(int i=0;i=职能指令手册)
返回;
int meio=分区(v、ini、fim);
快速排序(v、ini、meio-1、大小);
快速排序(v、meio+1、fim、大小);
}
内部分区(内部*v、内部ini、内部fim){
int i=ini-1,j=ini;
troca(五,(ini+fim)/2,fim);
int pivo=v[fim];
对于(;j 如果(v[j]线程创建不公平:线程1在线程2之前创建。此外,当创建线程1时,它可能会运行并抢占主线程,主线程可能会等待它返回CPU来创建和启动线程2。但是,在默认的SCHED#u OTHER策略下运行的线程具有不可预测的行为
要增加一些可预测性:
- 创建线程后,使线程同时启动。使用屏障同时触发所有线程的“go”。Cf
#包括
#包括
#包括
void troca(int*v,int i,int j);
内部分区(内部*v、内部ini、内部fim);
无效快速排序(int*v、int-ini、int-fim、int-size);
pthread_barrier_t barrier;
类型定义结构{
int-id;
int ini、mid、fim;
}线程参数;
整数大小;
int*v;
void*thread_func(void*arg){
线程_arg*a=arg;
pthread_barrier_wait(&barrier);
快速排序(v,a->ini,a->mid,a->fim);
printf(“在%d\n中完成”,a->id);
返回NULL;
}
int main()
{
//初始化
scanf(“%d”,大小(&S);
v=malloc(大小*尺寸(int));
//读取数组
对于(int i=0;i=职能指令手册)
返回;
int meio=分区(v、ini、fim);
快速排序(v、ini、meio-1、大小);
快速排序(v、meio+1、fim、大小);
}
内部分区(内部*v、内部ini、内部fim){
int i=ini-1,j=ini;
troca(五,(ini+fim)/2,fim);
int pivo=v[fim];
对于(;j
为了证明这一点,我在快速排序
中添加了一个unsigned long*
参数,并让它增加引用值
// thread and execution
pthread_create(&thread1, NULL, thread_func, &argument1);
printf("done out 1 (%d)\n", argument1.mid - argument1.ini + 1);
pthread_create(&thread2, NULL, thread_func, &argument2);
printf("done out 2 (%d)\n", argument2.mid - argument2.ini + 1);