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