簡體   English   中英

多線程自旋鎖?

[英]Multithreaded spin lock?

我的守護進程在它開始做它的事情之前在四個不同的線程中初始化它自己。 現在我使用一個計數器,它在線程啟動時遞增,在線程完成時遞減。 當計數器達到 0 時,我調用初始化完成回調。

這是首選的方法,還是有更好的方法? 我正在使用 POSIX 線程( pthread ),我只是運行一段while循環來等待計數器達到 0。

編輯: pthread_barrier_*函數在我的平台上不可用,盡管它們似乎是最好的選擇。

編輯 2:並非所有線程都退出。 一些初始化然后監聽事件。 基本上線程需要說,“我完成了初始化”。

你需要一個障礙。 它們是為此而創建的,當您需要在某些時間點“見面”然后再繼續時。 請參見 pthread_barrier_*

pthread_join 是等待 pthreads 的首選方式。

這聽起來很奇怪。 你不應該只是使用pthread_join()來等待線程完成嗎? 也許我不明白這個問題。

與其旋轉,不如使用 pthread mutex/condvar 原語。 我建議使用單個互斥鎖來保護未完成的線程數和 condvar。

主循環如下所示:

acquire mutex
count=N_THREADS;
start your N threads
while (1) {
  if (count==0) break;
  cond_wait(condvar);
}
release mutex

當每個線程准備就緒時,它會執行以下操作:

acquire mutex
count--
cond_signal(condvar)
release mutex

(編輯:我假設線程一旦完成初始化工作就會繼續運行。如果他們要完成,請使用pthread_join就像其他人所說的那樣。)

正如 Klas Lindbäck 在他的回答中指出的那樣,加入線程是 go 的首選方式。 如果您的線程沒有退出(即是可重用池的一部分等),邏輯聽起來不錯。 唯一的問題是在沒有任何同步的情況下使用計數器是危險的。 您必須使用帶條件的互斥鎖或原子 integer。 如果您不想在等待初始化完成的線程中旋轉原子計數器,我建議您使用互斥鎖 + 條件。

那么,如果一個線程在其他線程開始之前完成初始化會發生什么?

所以一種方法

  1. 將原子計數器初始化為 0
  2. 當每個線程都使用 init 完成時,遞增計數器並以原子方式檢索值。 如果你使用 GCC,你可以使用 __sync_add_and_fetch()
  3. 如果檢索到的計數器值 < N_threads,則阻塞 pthread 條件變量。
  4. 如果檢索到的計數器值 == N_threads,則初始化階段完成,發出條件信號並繼續。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM