繁体   English   中英

避免在pthread中产生多个线程

[英]Avoding multiple thread spawns in pthreads

我有一个使用pthreads并行化的应用程序。 该应用程序具有迭代例程调用,并且在常规例程中生成了一个线程(pthread_create和pthread_join),以并行化例程中的计算密集型部分。 当我使用PIN之类的检测工具来收集统计信息时,该工具会报告多个线程的统计信息(线程数x迭代次数)。 我相信这是因为每次调用例程时都会产生新的线程集。

  1. 如何确保仅创建一次线程,并且所有后续调用均使用首先创建的线程。

  2. 当我对OpenMP执行同样的操作,然后尝试收集统计信息时,我看到线程仅创建一次。 是因为OpenMP运行时吗?

编辑:

我给了代码的简化版本。

int main() 
{ 
  //some code 
  do { 
    compute_distance(objects,clusters, &delta); //routine with pthread 
  } while (delta > threshold ) 
}
void compute_distance(double **objects,double *clusters, double *delta) 
{ 
   //some code again 
   //computation moved to a separate parallel routine.. 
   for (i=0, i<nthreads;i++) 
     pthread_create(&thread[i],&attr,parallel_compute_phase,(void*)&ip); 
   for (i=0, i<nthreads;i++) 
     rc = pthread_join(thread[i], &status); 
} 

我希望这可以清楚地解释问题。

  1. 我们如何保存线程ID并测试是否已经创建?

您可以创建一个简单的线程池实现,该实现创建线程并使它们休眠。 一旦需要一个线程,而不是“ pthread_create”,您可以要求线程池子系统选择一个线程并完成所需的工作。这将确保您对线程数的控制。

使用最少的代码更改,您可以做的一件简单的事情就是为pthread_create和_join编写一些包装。 基本上,您可以执行以下操作:

typedef struct {
  volatile int go;
  volatile int done;
  pthread_t h;
  void* (*fn)(void*);
  void* args;
} pthread_w_t;

void* pthread_w_fn(void* args) {
    pthread_w_t* p = (pthread_w_t*)args;
    // just let the thread be killed at the end
    for(;;) {
        while (!p->go) { pthread_yield(); };  // yields are good
        p->go = 0;  // don't want to go again until told to
        p->fn(p->args);
        p->done = 1;
    }
}

int pthread_create_w(pthread_w_t* th, pthread_attr_t* a,
                     void* (*fn)(void*), void* args) {
    if (!th->h) {
        th->done = 0;
        th->go = 0;
        th->fn = fn;
        th->args = args;
        pthread_create(&th->h,a,pthread_w_fn,th);
    }
    th->done = 0; //make sure join won't return too soon
    th->go = 1;   //and let the wrapper function start the real thread code
}

int pthread_join_w(pthread_w_t*th) {
  while (!th->done) { pthread_yield(); };
}

然后必须更改调用和pthread_ts,或创建一些#define宏以将pthread_create更改为pthread_create_w等。。。必须将pthread_w_ts初始化为零。

但是,使用这些挥发物可能会很麻烦。 您可能需要花一些时间来获得我的粗略轮廓,才能真正正常工作。

为确保某些线程可能尝试执行的操作仅发生一次,请使用pthread_once() 为了确保只有一次线程可以完成某件事,只需使用bool (在静态存储中可能是一个bool )即可。

坦白地说,如果您要编辑问题(而不是注释,因为这会破坏格式)以包含所涉及的实际代码(包括OpenMP编译指示),那么对所有人回答您的问题会容易得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM