我如何修改我的函数只创建一个新线程而不是两个仍然实现相同的排序结果?

时间:2018-04-07 21:04:41

标签: c multithreading pthreads mergesort

我正在使用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;
}

如何进一步修改我的代码以仅创建一个新线程,但仍然可以获得与创建两个新线程的代码相同的排序结果?

1 个答案:

答案 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);

还有其他方法,我们可以重新安排事情的完成方式并使用轮询。但是,这是满足您要求所需的最简单/最小的更改。 (更改是第一个代码块)