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

using POSIX counting semaphore as a binary 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);

还有其他方法可以将计数信号量用作二进制信号量吗?在这里,如果在 while lopp 被评估为 false 之后立即发生 comtext 切换,但 sem_post 尚未被调用,在这种情况下不会导致竞争条件吗?对于我正在努力实现的目标,还有其他更好的解决方案吗?

我有多个进程正在与信号量同步。我知道这段代码不能保证一个场景,在 sem_getvalue 期间,即使 sem 值变为零,甚至在调用特定进程中的 sem_post 之前,另一个进程也可能调用sem_post, leading 值为2. 这种情况如何解决。

我的问题不会被互斥锁解决,因为在我的问题中,有些进程只用于信号,即 sem_post 操作,不像互斥锁,所有进程都会等待并不断发出信号

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

while(sem_getvalue(sem) > 0)

这称为忙等待,这意味着进程在信号量上自旋并且不会将 CPU 交给调度程序。通常,只有在等待时间小于上下文切换时间(例如低延迟)的情况下才会进行忙等待。

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

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

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

POSIX 变体将涉及 fcntl 而不是 flock