我正在使用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;
}
我如何进一步修改代码以仅创建一个新线程,但仍获得与创建两个新线程的代码相同的排序结果?
最佳答案
如果您想对父级排序一半,对子级排序第二个,那么这是一种可能的解决方案:
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);
还有其他方法,我们可以重新安排事情的完成方式并使用轮询。然而,这是满足您的要求所需的最简单/最小的更改。 (更改针对第一个代码块)
关于c - 我如何修改我的函数以仅创建一个新线程而不是两个,并且仍然获得相同的排序结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49711984/