为什么sem_open没有为同一个名字返回相同的值?

时间:2014-06-05 17:22:26

标签: c macos posix semaphore darwin

我按照sem_open's man page运行以下程序:

  

如果某个进程重复调用sem_open(),则使用相同的名称   参数,每次成功调用返回相同的描述符,   除非在过渡期间调用信号量sem_unlink()

我希望sem1sem2相等,但看起来并非如此。该程序将semaphores are not equal打印到stdout。

程序:

#include <err.h>
#include <semaphore.h>
#include <stdio.h>

int main(int argc, const char * argv[]) {
    const char *sem_name = "/sem";
    sem_t *sem1, *sem2;
    sem1 = sem_open(sem_name, O_CREAT, 0777, 0);
    sem2 = sem_open(sem_name, O_CREAT, 0777, 0);

    if (sem1 == SEM_FAILED || sem2 == SEM_FAILED) {
        printf("SEM_VALUE_MAX is %ud\n", SEM_VALUE_MAX);
        err(1, "SEM_FAILED");
    }

    if (sem1 != sem2) {
        printf("semaphores are not equal\n");
        return (2);
    }

    return (0);
}


有关我的环境的一些其他信息:

(jalcazar@mac ~)$ uname -a 
Darwin mac.local 13.2.0 Darwin Kernel Version 13.2.0: Thu Apr 17 23:03:13 PDT 2014; root:xnu-2422.100.13~1/RELEASE_X86_64 x86_64


The Open Group Base Specifications Issue 7 也说:

  

如果某个进程使用该进程多次成功调用sem_open()   名称的值相同,应返回相同的信号量地址   每次这样成功的电话。


我觉得我错过了一些非常基本的东西,但却找不到它是什么。
任何提示?



修改
稍微修改过的版本在 Ubuntu 13.04 FreeBSD 10.0 上按预期工作。
它在 OpenBSD 5.5 上打印semaphores are not equal但由于只有bbf44dc795572df9c53f06b4ba06c4e51d8660a7502b8a0cd0b2b43081af314f.sem/tmp中,因此假设它是相同的信号量是有意义的。

1 个答案:

答案 0 :(得分:0)

您无法将sem_t*==进行比较,以确定它是否是相同的信号量。 sem1 == sem2将检查twp指针是否相等,因为它们都来自同一个sem_open()调用,而不是它们引用相同的底层信号量。在这方面,OSX手册页的措辞听起来有点不诚实。

但是,您可以使用任何函数或运算符来检查两个sem_t*是否引用相同的信号量对象,虽然如果添加这些行,它的理由是exepct,如果输出是2:

int val = 9;
sem_post(sem1);
sem_post(sem1);
sem_getvalue(sem2, &val);
printf("sem2 value=%d\n", val);

sem_t*视为可能引用相同底层信号量的句柄。这非常类似于在同一个文件上调用open()两次,你得到两个不同的文件描述符,但它们仍然引用同一个文件。