我遇到以下代码的问题:
#include "updaterankparams.hpp"
int main()
{
sem_id = semget(SEM_KEY, 1, 0);
while(true)
{
printf("want to lower: %d\n", semctl(sem_id, 0, GETVAL));
semop(sem_id, &P, 1);
printf("lowered: %d\n", semctl(sem_id, 0, GETVAL));
scanf("%*c");
puts("t");
semop(sem_id, &V, 1);
}
return 0;
}
哪里
static sembuf P =
{
0,
-1,
0
};
static sembuf V =
{
0,
1,
0
};
我得到的输出是:
done
want to lower: 0
lowered: 0
t
want to lower: 1
lowered: 0
t
want to lower: 1
lowered: 0
当我进入字符以便在循环中满足printf时,它会在无限远处继续运行。 但是当我试图降低一个已经为零的信号量时,我希望该过程停止(休眠)。虽然,没有类似的事情发生!我知道这可能是一个愚蠢的问题,解决方案是微不足道的,但这是一个非常愚蠢的错误之一,没有人甚至没有在线请求解决方案,我想。
只是为了清除:没有其他进程使用信号量,并且已使用以下方法在其他(现已关闭)进程中初始化:
sem_id = semget(SEM_KEY, 1, 0666 | IPC_CREAT);
感谢帮助人员!
答案 0 :(得分:1)
TL; DR:您必须使用semget
创建信号量,然后给它一个"值"使用semop
,默认值为0(整齐:))。
从我得到的,你的P和V sembuf
分别是锁定和解锁,由1个资源。
编辑:您的信号量在开始时的值为0,因为您尚未对其进行初始化。看看示例given here即:
/* Semaphore does not exist - Create. */
if ((semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | S_IRUSR |
S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) != -1)
{
/* Initialize the semaphore. <- v THIS IS IMPORTANT v */
sbuf.sem_num = 0;
sbuf.sem_op = 2; /* This is the number of runs
without queuing. <- THIS IS WHERE YOU SET IT TO 1 */
sbuf.sem_flg = 0;
if (semop(semid, &sbuf, 1) == -1) {
perror("IPC error: semop"); exit(1);
}
}
我认为你混合了信号量的数量,以及同一个信号量中可用资源的数量,我做了。 semget
创建1个信号量,但您必须通过调用semop
将其设置为1个可用资源。一个信号量可以与多个可用资源一起使用(参见下面的火车示例)。
在while
循环中,您首先锁定信号量,使用行semop(sem_id, &P, 1);
,然后使用行{{>立即解锁 1}}。
这是在你的semop(sem_id, &V, 1);
,我猜你没有其他线程在运行,所以没有并发访问你的资源和信号量。您的程序永远不必等待因为信号量被锁定,您输入一个字符,信号量被解锁然后再次锁定在下一个循环中。当您尝试锁定它时,您的信号量值永远不会为0,因为它刚刚被释放。
如果您想尝试信号量并等待时间,请查看线程。一个很好的练习是尝试让3列火车只穿过1座桥,并有一个像这样的小展示,例如:
main
你的资源限制是桥梁(这里只有一个),你每列火车有一个线程,做同样的事情,比如:
[][][][]>--------________---------
[][][][]>-------- ---------
[][][][]>-------- ---------
如果你有2个桥,你仍然会有1个信号量/ sem_id,但是你可以将它设置为2个可用的资源,所以两个火车可以锁定&#34;同时使用相同的信号量。
我希望这可以帮助您理解为什么您没有等待程序的执行。