【问题标题】:sem_init on OS XOS X 上的 sem_init
【发布时间】:2010-11-27 16:18:31
【问题描述】:

我正在编写一些使用 pthread 和 semaphore 库的代码。 sem_init 函数在我的 Ubuntu 机器上运行良好,但在 OS X 上 sem_init 函数完全没有效果。图书馆有什么问题还是有不同的方法?这是我用来测试的代码。

sem_t sem1;
sem_t sem2;
sem_t sem3;
sem_t sem4;
sem_t sem5;
sem_t sem6;

sem_init(&sem1, 1, 1);
sem_init(&sem2, 1, 2);
sem_init(&sem3, 1, 3);
sem_init(&sem4, 1, 4);
sem_init(&sem5, 1, 5);
sem_init(&sem6, 1, 6);

这些值似乎是随机数,在sem_init 调用后它们不会改变。

【问题讨论】:

  • 你应该测试sem_init的返回值。
  • 请注意,至少在 Mac OS X Yosemite (10.10) 中,sem_init()sem_destroy()sem_getvalue() 被标记为“已弃用”并因此生成编译器警告。
  • @JonathanLeffler 哦,不。它无法在 Mac OS X Yosemite(10.10.1) 中运行。

标签: c macos pthreads semaphore


【解决方案1】:

不支持未命名信号量,您需要使用命名信号量。

要使用命名信号量而不是未命名信号量,请使用sem_open 代替sem_init,并使用sem_closesem_unlink 代替sem_destroy

【讨论】:

  • 哇。 <semaphore.h> 声明 sem_init 以便它在 OS X 上正确编译,但它返回 -1 并将 errno 设置为 ENOSYS(函数未实现)。
  • 好的,现在我正在寻找一个使用 C++ boost 库的信号量的好例子。我听说这是一个强大的实现
  • sem_getvalue() 也不起作用......见stackoverflow.com/questions/16655153/…
【解决方案2】:

Grand Central Dispatch 的 dispatch_semaphore_t 是比 OS X 上的命名信号量更好的解决方案(现在)。它的工作方式与未命名的 POSIX 信号量非常相似。

初始化信号量:

#include <dispatch/dispatch.h>
dispatch_semaphore_t semaphore;
semaphore = dispatch_semaphore_create(1); // init with value of 1

等待并发布(信号):

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
...
dispatch_semaphore_signal(semaphore);

销毁:

dispatch_release(semaphore);

头文件有据可查,我发现它很容易使用。

【讨论】:

  • GCD 信号量是 GCD 级别的功能。从理论上讲,如果与 pthread 级别结合使用,可能会导致一些问题。
  • @Eonil 你能详细说明一下吗?你会遇到什么样的问题?
  • @MichaelDorst 错误的问题。基本上,您不应该使用暴露在不同抽象上的 API 来控制另一个抽象,除非它们被明确设计为一起工作。即使您知道所有细节并且它们现在正在工作,因为实施细节可能会在以后更改。如果您没有互操作性的证据,则由于潜在问题,您应该假设此类使用不安全。并且没有证据表明 GCD API 将按预期在 POSIX 线程中工作。
  • @MichaelDorst 正确的问题是“有什么证据表明 GCD API 可以用于 POSIX 线程?”没有证据就意味着不安全。
  • @MichaelDorst GCD 不是帮助 pthread 的“扩展”或“实用程序”功能。它是一个独立且不透明的抽象,不依赖于实现细节。
【解决方案3】:

如果您查看源代码中 sem_init 的实现,那么它只会返回一个错误,而其他一些 bsd fns(如 sem_open)仍然有实现。

“已弃用”的 posix fns 和 libdispatch/GCD 都使用 fns 从用户空间调用,例如 semphore_create 和 semaphore_wait。如果您想要一个始终使用内核/操作系统的旧式 sema,您可以直接使用它们,但您最好使用像 GCD 这样在内部使用原子计数器并且仅在必须等待时才调用内核/操作系统的 sema。

https://github.com/apple/darwin-xnu/blob/a1babec6b135d1f35b2590a1990af3c5c5393479/bsd/kern/posix_sem.c

【讨论】:

    猜你喜欢
    • 2015-02-28
    • 2011-03-03
    • 2010-10-03
    • 2014-01-31
    • 1970-01-01
    • 2015-12-24
    • 2011-08-24
    • 2012-08-09
    相关资源
    最近更新 更多