【问题标题】:Semaphore value initialized to -1?信号量值初始化为-1?
【发布时间】:2015-05-16 14:22:21
【问题描述】:

我正在尝试为一些共享内存初始化二进制信号量。我不知道为什么我挂在一个信号量上来获取信号量,最终发现信号量值是-1,我一直在等待。我不明白为什么信号量值初始化为 -1 开始。任何澄清这一点的帮助将不胜感激。

semID = semget(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR); // create sem
int semval = semctl(semID, 1,GETVAL);

printf("After init Semaphore value = %d \n", semval);
printf("sem ID = %d \n", semID);

输出:

 After init semaphore value = -1 
 sem ID = 524304 

【问题讨论】:

  • RTFM:“失败时,semctl() 返回 -1,errno 指示错误。”

标签: c ipc semaphore


【解决方案1】:

你有两个错误。您的第一个错误是,与 C 中的往常一样,semget 创建的信号量数组是 0-indexed;因此,如果您只创建一个信号量,semctl 的第二个参数与 semid 应该是 0,而不是 1。您从 semctl 返回的 -1 不是信号量的值,而是错误提示(你应该会发现errno == EINVAL)。

您的第二个错误更加微妙。 The POSIX.1-2008 specification for semget 说:

创建后,...

  • 与集合中每个信号量相关的数据结构不需要初始化。带有命令SETVALSETALLsemctl() 函数可用于初始化每个信号量。

(强调我的)这意味着,您的代码在首次创建时不能依赖具有 any 特定值的新 SysV 信号量。你必须这样做:

semID = semget(IPC_PRIVATE, 1, S_IRUSR|S_IWUSR);
if (semID < 0) {
    perror("semget");
    return -1;
}

union semun arg;
arg.val = 0;
if (semctl(semID, 0, SETVAL, arg) == -1) {
    perror("semctl");
    return -1;
}

// only now is it safe to use the semaphore

请注意,您必须将文档中union semun 的定义复制到您的代码中;它不是由任何标题提供的。

如果您开始觉得这个 API 很糟糕,那么您是 100% 正确的。您可能会发现 semaphore.h API 更合适,但它不那么普遍。

【讨论】:

    【解决方案2】:

    实际上,man page for semctl 告诉您返回值 -1 表示发生错误。

    要获取错误,请使用 strerror printf( "%s", strerror(errno) );

    别忘了#include &lt;errno.h&gt;#include &lt;string.h&gt;

    【讨论】:

    • 应该知道对 -1... 多哈... 谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多