信号量不会使进程睡眠

时间:2014-05-12 09:01:19

标签: c linux ipc semaphore sem

我遇到以下代码的问题:

#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);

感谢帮助人员!

1 个答案:

答案 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;同时使用相同的信号量。

我希望这可以帮助您理解为什么您没有等待程序的执行。