多线程自旋锁?

时间:2011-05-26 13:34:03

标签: c pthreads

我的守护进程在开始执行其操作之前在四个不同的线程中初始化自己。现在我使用一个计数器,它在线程启动时递增,在完成时递减。当计数器达到0时,我调用初始化完成的回调。

这是首选的方法,还是有更好的方法?我正在使用POSIX线程(pthread)而我只是运行while周期等待计数器达到0。

编辑: pthread_barrier_*功能在我的平台上不可用,尽管它们似乎确实是最佳选择。

编辑2:并非所有线程都退出。一些初始化然后听取事件。基本上线程需要说,“我已经完成了初始化”。

6 个答案:

答案 0 :(得分:7)

你需要一个障碍。它们是为此而创建的,当你需要在继续之前在某些点“见面”时。见pthread_barrier_t *

答案 1 :(得分:3)

pthread_join是等待pthreads的首选方式。

答案 2 :(得分:3)

听起来很奇怪。您是否应该只使用pthread_join()等待线程完成?也许我不明白这个问题。

答案 3 :(得分:3)

使用pthread互斥/ 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,正如其他人所说的那样。)

答案 4 :(得分:0)

正如KlasLindbäck在答案中指出的那样,加入线程是一种首选方式。 如果您的线程没有退出(即可重用池的一部分等),逻辑听起来不错。唯一的事情是使用没有任何同步的计数器是危险的。您必须使用具有条件或原子整数的互斥锁。如果你不想在等待初始化完成的线程中使用原子计数器,我建议使用互斥+条件。

答案 5 :(得分:0)

那么,如果一个线程在任何其他线程开始之前完成初始化会发生什么?

所以有一种方法可以做到这一点

  1. 将原子计数器初始化为0
  2. 当每个线程使用init完成时,递增计数器并以原子方式检索该值。如果您使用GCC,则可以使用__sync_add_and_fetch()
  3. 如果检索到的计数器值< N_threads,阻塞pthread条件变量。
  4. 如果检索到的计数器值== N_threads,则初始阶段完成,发出状态信号并继续。