【问题标题】:Odd/Incorrect sem_getvalue Semaphore Behavior on OS XOS X 上的奇数/错误 sem_getvalue 信号量行为
【发布时间】: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 会返回如此奇怪的结果...

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

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

【问题讨论】:

    标签: c++ macos posix mutex semaphore


    【解决方案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)。
    • 我发布了一个后续内容,其中包含他的代码失败的原因:stackoverflow.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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多