我正在尝试为一些共享内存初始化一个二进制信号量。我不知道为什么我挂在一个信号量得到信号量,并最终发现信号量值是-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
发布于 2015-03-13 15:30:37
你有两个虫子。第一个错误是,和C中一样,semget
创建的信号量数组是0索引的;因此,如果您只创建一个信号量,那么使用该semid
的semctl
的第二个参数应该是0,而不是1。从semctl
返回的-1不是信号量的值,而是一个错误指示(您应该找到errno == EINVAL
)。
你的第二个bug更微妙。semget
说:
创造的时候..。
SETVAL
或SETALL
的SETVAL
函数来初始化每个信号量。(强调我的意思)这意味着,您的代码在第一次创建时不能依赖具有任何特定值的新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很糟糕,那么您就完全正确了。您可能会发现semaphore.h
API更合适,但是它不太普遍。
https://stackoverflow.com/questions/29043477
复制