2011-11-24 73 views
2

僞代碼障礙:如何處理與線程退出

void * thread_start(void *arg) { 
    while (1) { 
     /* for each column. Only run columns the thread_num 
      is assigned to */ 
     column_count = thread_num; 
     for (; column_count < dim - 1; column_count+=threads) { 
      /* do thread work for data chunk */ 
     } 

     /* barrier */ 
     barrier_result = pthread_barrier_wait(barrier); 

     if (not_finished == 0) { 
      /* finished */ 
      break; 
      /* break while loop, end thread. 
       The barrier is now broken because it is no longer 
       getting called by this thread */ 
     } 

     /* we are not finished, loop around and 
      do thread work on next data chunk */ 
    } 
} 

我與障礙的問題是你如何處理與其它線程之前結束線程?

屏障意味着每個線程必須等待每個其他線程。

有什麼技術可以確保所有線程同時結束?

我試圖延續着的循環,但忽視了「線程的工作」,但在這種情況下,所有8個線程完成,有沒有合理的方式來告訴線程「你都做,你現在可以全部退出」

編輯:

算法:

  1. 上的數據塊
  2. 段運行操作,如果數據塊的線程的段完成termina TE。
  3. 障礙等待。
  4. 一個線程替換一塊數據有一些新的數據
  5. 重複1

編輯2:

有覆蓋一個屏障,一個阻隔任何優雅的方式尺寸較小? (無需在屏障上放置互斥鎖)

+1

甚至沒有不雅的方式:),你不能複製另一個障礙或在相同的障礙上多次調用'pthread_barrier_init'。 – chill

回答

0

確保線程在程序邏輯的本質中同時結束。如果算法調用線程在不同的時間退出,那麼對於該具體算法來說,障礙並不是合適的併發控制機制。

編輯:

你可以原子方式增加了「finished_count」和循環,沒有做任何工作,然後其他參與的障礙,而這一數字小於屏障計數(保護讀取/寫入finished_count與適當的互斥體)。

編輯: 我不知道如果我理解你的附加說明好了,我只是寫此基礎上你的原代碼,也許它會爲你工作:

int finished_count; 

void * thread_start(void *arg) { 
    int finished = 0; 

    while (1) { 

     if (finished) { 
      pthread_mutex_lock (&finished_lock); 
      if (finished_count == 8) { 
       pthread_mutex_unlock (&finished_lock); 
       break; 
      } 
      pthread_mutex_unlock (&finished_lock); 
     } else { 
      /* for each column. Only run columns the thread_num 
       is assigned to */ 
      column_count = thread_num; 
      for (; column_count < dim - 1; column_count+=threads) { 
       /* do thread work for data chunk */ 
      } 

      /* set "finished" as appropriate */ 

      /* Check if we have just finished. */ 
      if (finished) { 
       pthread_mutex_lock (&finished_lock); 
       ++finished_count; 
       pthread_mutex_unlock (&finished_lock); 
      } 
     } 

     barrier_result = pthread_barrier_wait(barrier); 
    } 

    return 0; 
} 

編輯:

爲了澄清上述有關複製過或重新初始化我的意見,說POSIX:

http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_barrier_init.html

如果調用pthread_barrier_init()指定已經初始化的障礙,則結果未定義。

僅可被用於執行同步由屏障引用的對象。在對pthread_barrier_destroy()或pthread_barrier_wait()的調用中引用該對象的副本的結果未定義。

+0

我用我的「算法」的描述更新了問題。你有什麼建議嗎? – Raynos

+0

你明白了這個問題。我將不得不保持完成計數。替代方案是用新的較小屏障覆蓋屏障。我不知道哪個更高性能。 – Raynos

+0

變成了,而不是保留一個「線程完成」的計數器,並等待到n。應該爲「線程未完成」保留標誌,並且如果n個線程中沒有一個線程「未完成」 – Raynos