简体   繁体   English

避免在pthread中产生多个线程

[英]Avoding multiple thread spawns in pthreads

I have an application that is parallellized using pthreads. 我有一个使用pthreads并行化的应用程序。 The application has a iterative routine call and a thread spawn within the rountine (pthread_create and pthread_join) to parallelize the computation intensive section in the routine. 该应用程序具有迭代例程调用,并且在常规例程中生成了一个线程(pthread_create和pthread_join),以并行化例程中的计算密集型部分。 When I use an instrumenting tool like PIN to collect the statistics the tool reports statistics for several threads(no of threads x no of iterations). 当我使用PIN之类的检测工具来收集统计信息时,该工具会报告多个线程的统计信息(线程数x迭代次数)。 I beleive it is because it is spawning new set of threads each time the routine is called. 我相信这是因为每次调用例程时都会产生新的线程集。

  1. How can I ensure that I create the thread only once and all successive calls use the threads that have been created first. 如何确保仅创建一次线程,并且所有后续调用均使用首先创建的线程。

  2. When I do the same with OpenMP and then try to collect the statistics, I see that the threads are created only once. 当我对OpenMP执行同样的操作,然后尝试收集统计信息时,我看到线程仅创建一次。 Is it beacause of the OpenMP runtime ? 是因为OpenMP运行时吗?

EDIT: 编辑:

im jus giving a simplified version of the code. 我给了代码的简化版本。

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); 
} 

I hope this clearly explains the problem. 我希望这可以清楚地解释问题。

  1. How do we save the thread id and test if was already created? 我们如何保存线程ID并测试是否已经创建?

You can make a simple thread pool implementation which creates threads and makes them sleep. 您可以创建一个简单的线程池实现,该实现创建线程并使它们休眠。 Once a thread is required, instead of "pthread_create", you can ask the thread pool subsystem to pick up a thread and do the required work.. This will ensure your control over the number of threads.. 一旦需要一个线程,而不是“ pthread_create”,您可以要求线程池子系统选择一个线程并完成所需的工作。这将确保您对线程数的控制。

An easy thing you can do with minimal code changes is to write some wrappers for pthread_create and _join. 使用最少的代码更改,您可以做的一件简单的事情就是为pthread_create和_join编写一些包装。 Basically you can do something like: 基本上,您可以执行以下操作:

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(); };
}

and then you'll have to change your calls and pthread_ts, or create some #define macros to change pthread_create to pthread_create_w etc....and you'll have to init your pthread_w_ts to zero. 然后必须更改调用和pthread_ts,或创建一些#define宏以将pthread_create更改为pthread_create_w等。。。必须将pthread_w_ts初始化为零。

Messing with those volatiles can be troublesome though. 但是,使用这些挥发物可能会很麻烦。 you'll probably need to spend some time getting my rough outline to actually work properly. 您可能需要花一些时间来获得我的粗略轮廓,才能真正正常工作。

To ensure something that several threads might try to do only happens once, use pthread_once() . 为确保某些线程可能尝试执行的操作仅发生一次,请使用pthread_once() To ensure something only happens once that might be done by a single thread, just use a bool (likely one in static storage). 为了确保只有一次线程可以完成某件事,只需使用bool (在静态存储中可能是一个bool )即可。

Honestly, it would be far easier to answer your question for everyone if you would edit your question – not comment, since that destroys formatting – to contain the real code in question, including the OpenMP pragmas. 坦白地说,如果您要编辑问题(而不是注释,因为这会破坏格式)以包含所涉及的实际代码(包括OpenMP编译指示),那么对所有人回答您的问题会容易得多。

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

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