簡體   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