pthread-win32扩展名sem_post_multiple

时间:2010-12-02 21:50:45

标签: c++ c multithreading posix pthreads-win32

我目前正在构建一个围绕pthreads的瘦C ++包装器,供内部使用。 Windows和QNX都是目标,幸运的是pthreads-win32端口似乎运行良好,而QNX符合我们实际目的的POSIX。

现在,在实现信号量时,我点击了函数

sem_post_multiple(sem_t*, int)

显然仅在pthreads-win32上可用,但在QNX中缺失。顾名思义,该函数应该通过作为第二个参数给出的计数来增加信号量。据我所知,该功能既不是POSIX 1b也不是POSIX 1c的一部分。

虽然目前没有要求所述功能,但我仍然想知道为什么pthreads-win32提供该功能以及它是否可能有用。我可以尝试使用类似于以下内容来模仿QNX:

sem_post_multiple_qnx(sem_t* sem, int count)
{
   for(;count > 0; --count)
   {
       sem_post(sem);
   }
} 

我要求的是关于如何进行的建议/建议。如果共识建议实现QNX的功能,我也希望评论所建议的代码是否是可行的解决方案。

提前致谢。

PS:为了清晰起见,我故意遗漏了我喜欢的C ++课程。对于所有建议加强救援的人:由于管理原因,它不是我当前项目的一个选项。

4 个答案:

答案 0 :(得分:1)

您提议的sem_post_multiple实施与sem_getvalue的效果不佳,因为sem_post_multiple是原子增加,因此无法同时调用sem_getvalue返回任何中间值。

就我个人而言,我想把它们都抛弃:尝试将基本的同步操作添加到一个缺少它们的系统是一个杯子的游戏,你的包装可能很快就会停止“瘦”。所以不要进入它,除非你的代码使用sem_post_multiple,你绝对必须移植。

答案 1 :(得分:1)

在任何情况下,信号量都是POSIX中的可选扩展名。例如,OS X似乎没有完全实现它们。因此,如果您担心可移植性,无论如何都必须提供所需功能的包装。

您通过迭代sem_post模拟原子增量的方法肯定存在缺点。

  • 可能表现不佳, 通常使用sem_t的地方 绩效关键环境。
  • 此操作不会 原子。令人困惑的事情可能会 在你完成循环之前发生。

我会坚持刚刚必要的,严格遵守POSIX。请注意sem_timedwait是信号量选项的另一个可选部分。

答案 2 :(得分:0)

sem_post_multiple()是win32-pthreads维护者引入的非标准辅助函数。您的实现与他们的实现不同,因为多次递减不是原子的。这是否是一个问题取决于预期用途。 (就个人而言,除非/在需要之前,否则我不会尝试实施此功能。)

答案 3 :(得分:0)

这是一个有趣的问题。 +1。

我同意目前的普遍共识,即实施该功能可能不是一个好主意。虽然您提出的实现在大多数情况下可能会正常工作,但由于非原子性,结果可能会有很大差异。以下是一个(非常)人为的情况:

  • 启动调用sem_post_multiple(s,10)
  • 的线程A.
  • 等待s的线程B被释放。线程B杀死线程A。

在上述不友好的场景中,原子版本会使信号量增加10.对于非原子版本,它只能递增一次。这个例子在现实世界中肯定不太可能。例如,杀死一个线程几乎总是一个坏主意,更不用说它可能使信号量对象处于无效状态。 Win32实现可能会在信号量上留下互斥锁 - see this for why