问题描述
|
我的守护程序在开始执行操作之前会在四个不同的线程中进行初始化。现在,我使用一个计数器,该计数器在线程启动时递增,在线程结束时递减。当计数器达到0时,我将调用初始化完成的回调。
这是首选的方法,还是有更好的方法?我正在使用POSIX线程(
pthread
),我只是运行while
周期来等待计数器达到0。
编辑:pthread_barrier_*
函数在我的平台上不可用,尽管它们似乎是最佳选择。
编辑2:并非所有线程都退出。一些初始化然后监听事件。基本上,线程需要说“我已完成初始化”。
解决方法
不用旋转,而是使用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
,如其他人所说。)
,您需要的是障碍。它们是为此创建的,当您需要在某些时候“开会”然后继续之前。参见pthread_barrier_ *
,pthread_join是等待pthread的首选方法。
,这听起来很奇怪。您不应该只使用pthread_join()等待线程完成吗?也许我不明白这个问题。
,正如KlasLindbäck在回答中指出的那样,加入线程是首选的方式。
如果您的线程没有退出(即属于可重用池等),则逻辑听起来不错。唯一的事情就是使用没有任何同步的计数器是危险的。您必须使用带条件的互斥量或原子整数。如果您不想在等待初始化完成的线程中启动原子计数器,则建议使用互斥+条件。
,那么,如果一个线程在其他任何线程开始之前完成了初始化会发生什么呢?
所以一种方法
将原子计数器初始化为0
当每个线程都使用init完成后,递增计数器并自动获取该值。如果使用GCC,则可以使用__sync_add_and_fetch()
如果检索到的计数器值