繁体   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