OS X 上的奇数/错误 sem_getvalue 信号量行为

Posted

技术标签:

【中文标题】OS X 上的奇数/错误 sem_getvalue 信号量行为【英文标题】:Odd/Incorrect sem_getvalue Semaphore Behavior on OS X 【发布时间】:2009-05-16 01:29:57 【问题描述】:

我有一些非常基本的信号量代码,它们在 Linux 上运行良好,但我一辈子都无法让它在 OS X 上正常运行...它返回最奇怪的结果...

#include <iostream>
#include <fcntl.h>
#include <stdio.h>
#include <semaphore.h>

int main()

    sem_t* test;
    test = sem_open("test", O_CREAT, 0, 1);

    int value;
    sem_getvalue(test, &value);
    printf("Semaphore initialized to %d\n", value);

在 OS X 上使用 g++ 编译它会返回以下输出:

iQudsi:Desktop mqudsi$ g++ test.cpp
iQudsi:Desktop mqudsi$ ./a.out 
Semaphore initialized to -1881139893

而在 Ubuntu 上,我得到的结果显然更加理智:

iQudsi: Desktop mqudsi$ g++ test.cpp -lrt
iQudsi:Desktop mqudsi$ ./a.out 
Semaphore initialized to 1

我已经连续研究了 3 个小时,无法弄清楚为什么 OS X 会返回如此奇怪的结果...

我尝试使用文件路径作为信号量名称,但没有任何区别。

如果能得到任何帮助,我将不胜感激。

【问题讨论】:

【参考方案1】:

您是否在测试错误?试试:

#include <iostream>
#include <fcntl.h>
#include <stdio.h>
#include <semaphore.h>

int main()

    sem_t* test;
    test = sem_open("test", O_CREAT, 0, 1);
    if (test == SEM_FAILED) 
        perror("sem_open");
        return 1;
    

    int value;
    if (sem_getvalue(test, &value)) 
        perror("sem_getvalue");
        return 1;
    
    printf("Semaphore initialized to %d\n", value);

【讨论】:

第一个检查应该是“if (test == SEM_FAILED)”而不是 !test,因为这是记录在案的失败值(实际上是 -1,而不是 0)。 我发布了一个后续内容,其中包含他的代码失败的原因:***.com/questions/871435/…【参考方案2】:
$ g++ sem-testing.cc -Wall
$ ./a.out 
sem_getvalue: Function not implemented
$ man sem_getvalue
No manual entry for sem_getvalue

您正在使用当前未在 Mac OS X 中实现的函数,并且您正在打印的整数包含初始化整数的默认数据,该数据可能是仍在内存中的随机数据。如果您将其归零,通过将其设置为int value = 0;,您可能会更早发现此错误。

这是我使用的代码(感谢bdonlan):

#include <iostream>
#include <fcntl.h>
#include <stdio.h>
#include <semaphore.h>

int main()

    sem_t* test;
    test = sem_open("test", O_CREAT, 0, 1);
    if (test == SEM_FAILED) 
        perror("sem_open");
        return 1;
    

    int value;
    if (sem_getvalue(test, &value)) 
        perror("sem_getvalue");
        return 1;
    
    printf("Semaphore initialized to %d\n", value);

【讨论】:

【参考方案3】:

好吧,也许 sem_open() 失败了——你没有测试。

或者,也许 OSX 不默认支持共享 posix sem - 如果 /dev/shm 没有挂载,通常系统将不支持 sem_open()。

您可能想要使用 SysV 信号量。

这里提出了关于 Slackware 的类似问题:how-do-i-stop-semopen-failing-with-enosys

然而,进一步的搜索显示 OSX 命名的信号机是建立在马赫信号量之上的,当你完成时你可能需要 sem_unlink() (不仅仅是 sem_close(),或者可能是相反),你应该小心关于权限 - 我建议从 0777 或 0700 开始,而不是 0。请参阅 posiz semaphores in Darwin

【讨论】:

以上是关于OS X 上的奇数/错误 sem_getvalue 信号量行为的主要内容,如果未能解决你的问题,请参考以下文章

OS X El Capitan 上的 MySQLdb 错误

RE 错误:Mac OS X 上的非法字节序列

Mac OS X Mojave 上的 XAMPP 错误

Mac OS X 上的 GLSL 版本 130 导致错误 [关闭]

将小的 .sql 文件上传到 MySQL 数据库文件返回错误(OS X 上的 XAMPP)

OS X El Capitan 上的 MySQL 5.7.9:错误服务器退出而不更新 PID 文件