4

我目前正在围绕 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

4 回答 4

1

您提议的实现sem_post_multiple不能很好地使用sem_getvalue,因为这sem_post_multiple是一个原子增加,因此“同时”调用不可能sem_getvalue返回任何中间值。

就我个人而言,我希望将它们都排除在外:尝试将基本同步操作添加到缺少它们的系统中是一种愚蠢的游戏,并且您的包装器可能很快就会不再“瘦”。所以除非你有使用的代码,否则不要进入它sem_post_multiple,你绝对必须移植。

于 2010-12-02T22:01:51.647 回答
1

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

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

  • 它可能表现不佳,通常 sem_t用于性能关键的上下文中。
  • 这个操作不会是原子的。所以在你完成循环之前可能会发生令人困惑的事情。

我会坚持必要的、严格符合 POSIX 的要求。请注意,这sem_timedwait是信号量选项的另一个可选部分。

于 2010-12-02T22:02:23.183 回答
0

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

于 2010-12-02T22:01:09.703 回答
0

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

我同意这里目前普遍存在的共识,即实现该功能可能不是一个好主意。虽然您提议的实现在大多数情况下可能都可以正常工作,但由于非原子性,肯定存在结果可能会大不相同的情况。以下是一种(非常)人为的情况:

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

In the above unfriendly scenario, the atomic version would have incremented the semaphore by 10. With non-atomic version, it may only be incremented once. This example is certainly not likely in the real world. For example, the killing of a thread is almost always a bad idea not to mention the fact that it could leave the semaphore object in an invalid state. The Win32 implementation could leave a mutex lock on the semaphore - see this for why.

于 2010-12-02T22:26:41.417 回答