我正在使用pthreads
编写并行合并排序。现在,我正在创建两个线程,每个线程对数据的一半进行排序。然后合并这两个线程的结果。但是,我试图在函数中更改我的代码而不创建只有1个线程而不修改现有参数或函数的返回类型。
所以,我试图让函数首先对数据本身进行排序,然后只创建一个新线程(而不是两个)来对另一半进行排序。
这是我为函数编写的代码,它创建了两个线程:
// sort and return float array x, of length n
// using merge sort
void *pmerge_sort(void *args) {
// unpack arguments
Sort_args *sargs = (Sort_args *)args;
float *x = sargs->x;
int n = sargs->len;
// if n < k, the array is sorted directly
// using another sort algorithm
int k = 100;
if (n < k) {
return(gsort(x, n));
}
// create 2 threads; each sorts half the data
int m = ((float)n)/2.0;
// pack arguments to recursive call
Sort_args args1, args2;
args1.x = x;
args1.len = m;
args2.x = &x[m];
args2.len = n-m;
int rc;
pthread_t p1, p2;
rc = pthread_create(&p1, NULL, pmerge_sort, (void *)&args1); assert(rc == 0);
rc = pthread_create(&p2, NULL, pmerge_sort, (void *)&args2); assert(rc == 0);
// merge the results from the threads
float *x1, *x2;
pthread_join(p1, (void **) &x1);
pthread_join(p2, (void **) &x2);
float *y = merge(x1, m, x2, n-m);
// copy the result back to x and free y
memcpy((void *)x, (void *)y, n*sizeof(float));
free(y);
return (void *)x;
}
如何进一步修改我的代码以仅创建一个新线程,但仍然可以获得与创建两个新线程的代码相同的排序结果?
答案 0 :(得分:1)
如果你想在父母身上排序一半而在孩子身上排第二,那么这里有一个可能的解决方案:
int rc;
pthread_t p;
rc = pthread_create(&p, NULL, pmerge_sort, (void *)&args1); assert(rc == 0);
// merge the results from the threads
float *x1, *x2;
// let worker thread finish first
pthread_join(p, (void **) &x1);
// then sort other half here
x2 = (float*)(*pmerge_sort)((void *)&args2);
// then merge
float *y = merge(x1, m, x2, n-m);
还有其他方法,我们可以重新安排事情的完成方式并使用轮询。但是,这是满足您要求所需的最简单/最小的更改。 (更改是第一个代码块)