C 信号量值初始化为-1?

C 信号量值初始化为-1?,c,ipc,semaphore,C,Ipc,Semaphore,我正在尝试初始化某个共享内存的二进制信号量。我不明白为什么我挂起一个semop来获取信号量,最终发现信号量值为-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 \

我正在尝试初始化某个共享内存的二进制信号量。我不明白为什么我挂起一个semop来获取信号量,最终发现信号量值为-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 
实际上,返回值告诉您返回值-1意味着有错误

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

不要忘记
#include
#include
实际上,返回值-1表示有错误

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


别忘了
#include
#include
你有两个bug。您的第一个错误是,像在C中一样,
semget
创建的信号量数组是0索引的;因此,如果只创建一个信号量,则使用该
semid
semctl
的第二个参数应该是0,而不是1。从
semctl
返回的-1不是信号量的值,而是一个错误指示(您应该发现
errno==EINVAL

你的第二个bug更微妙。说:

一经创造

  • 与集合中每个信号量相关联的数据结构不需要初始化。带有命令
    SETVAL
    SETALL
    的函数可用于初始化每个信号量
(我的重点)这意味着,您的代码在第一次创建时不能依赖具有任何特定值的新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
semID=semget(IPC_PRIVATE,1,S_IRUSR | S_IWUSR);
if(semID<0){
perror(“semget”);
返回-1;
}
联合塞蒙阿格;
arg.val=0;
if(semctl(semID,0,SETVAL,arg)=-1){
perror(“semctl”);
返回-1;
}
//只有现在使用信号灯才安全
请注意,您必须将
union-semun
的定义从文档中复制到代码中;它不是由任何标题提供的


如果您开始觉得这个API很糟糕,那么您是100%正确的。您可能会发现API更适合您,但是它的应用范围较小。

您有两个bug。您的第一个错误是,像在C中一样,
semget
创建的信号量数组是0索引的;因此,如果只创建一个信号量,则使用该
semid
semctl
的第二个参数应该是0,而不是1。从
semctl
返回的-1不是信号量的值,而是一个错误指示(您应该发现
errno==EINVAL

你的第二个bug更微妙。说:

一经创造

  • 与集合中每个信号量相关联的数据结构不需要初始化。带有命令
    SETVAL
    SETALL
    的函数可用于初始化每个信号量
(我的重点)这意味着,您的代码在第一次创建时不能依赖具有任何特定值的新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
semID=semget(IPC_PRIVATE,1,S_IRUSR | S_IWUSR);
if(semID<0){
perror(“semget”);
返回-1;
}
联合塞蒙阿格;
arg.val=0;
if(semctl(semID,0,SETVAL,arg)=-1){
perror(“semctl”);
返回-1;
}
//只有现在使用信号灯才安全
请注意,您必须将
union-semun
的定义从文档中复制到代码中;它不是由任何标题提供的


如果您开始觉得这个API很糟糕,那么您是100%正确的。您可能会发现API更适合,但它的应用范围较小。

RTFM:“失败时,semctl()返回-1,errno表示错误。”RTFM:“失败时,semctl()返回-1,errno表示错误。”应该知道会怀疑-1。。。嗯。。。谢天谢地应该知道他怀疑a-1。。。嗯。。。谢谢