使用POSIX计数信号量作为二进制信号量

时间:2015-08-23 04:32:26

标签: c linux posix ipc semaphore

我正在尝试将POSIX counting semaphore用作binary semaphore

为此,我编写了以下代码

sem = sem_open(argv[optind], flags, perms, 1); // Initialising semaphore to 1

    while(sem_getvalue(sem) > 0)
    {
    continue;

    }
    sem_post(sem);

还有其他方法可以将计数信号量用作二进制信号量吗?如果在lopp被唤醒为假之后立即发生comtext切换,但是sem_post还没有被调用,那么在这种情况下不会导致竞争条件?对于我想要实现的目标,还有其他更好的灵魂。

我有多个进程与sempahore同步。我知道这个代码不保证一个场景,当sem_getvalue期间即使sem值变为零,甚至在调用特定进程中的sem_post之前,anotehr进程也可以调用sem_post,导致值为2如何解决这种情况。

我的问题不会被互斥锁解决,就像在我的问题中一样,有些进程仅用于信号即sem_post操作,这与mutex不同,其中所有进程都将等待并不断发出信号

1 个答案:

答案 0 :(得分:0)

您发布的代码存在一些问题。

<T>

这称为忙等待,这意味着进程在信号量上旋转,并且不会将CPU放弃到调度程序。通常,繁忙等待仅在等待时间应小于上下文切换时间(例如低等待时间)的情况下完成。

下一个问题是你的语义被颠倒了。当信号量大于0时,你递减并继续。另外,你的调用不是原子的,这引入了许多竞争条件。

实际上,你需要互斥语义,因为只有两种状态(0 /锁定和1 /解锁)。为此,您可以保证while(sem_getvalue(sem) > 0) 永远不会进行sem_post,也可以使用文件锁定。

sem_wait

POSIX变体将涉及const char* lock_file = ".lock"; const int fd_lock = open(lock_file, O_CREAT); flock(fd_lock, LOCK_EX); // do stuff flock(fd_lock, LOCK_UN); // do more stuff close(fd_lock); unlink(lock_file); 而不是fcntl