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

C 使用POSIX计数信号量作为二进制信号量,c,linux,posix,ipc,semaphore,C,Linux,Posix,Ipc,Semaphore,我试图使用POSIX计数信号量作为二进制信号量 为此,我编写了以下代码 sem = sem_open(argv[optind], flags, perms, 1); // Initialising semaphore to 1 while(sem_getvalue(sem) > 0) { continue; } sem_post(sem); 是否有其他方法将计数信号量用作二进制信号量?在这里,如果comtext切换在while lopp被评估为

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

为此,我编写了以下代码

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

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

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

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


我的问题不会通过互斥来解决,因为在我的问题中,有一些进程只用于信号,即
sem\u post
操作,这与互斥不同,在互斥中,所有进程都会等待并不断发出信号

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

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

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

实际上,您需要互斥语义,因为只有两种状态(0/locked和1/unlocked)。为此,您可以保证
sem\u post
不会执行
sem\u 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

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

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

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

实际上,您需要互斥语义,因为只有两种状态(0/locked和1/unlocked)。为此,您可以保证
sem\u post
不会执行
sem\u 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

。可能。使用文件锁不会减慢进程,因为文件操作会造成不必要的延迟。这里还可以有多个进程,可以执行信号量信号操作。事实上,有些进程只执行信号操作。所以这不是一个典型的互斥操作。感谢您的输入,但我正在寻找一个基于信号量的解决方案,而不是文件锁操作。不,互斥、信号量和文件锁都是在内核中实现的,因为进程需要对它们进行阻塞。锁定文件通常为空,锁定/解锁并不意味着任何I/O。您所描述的语义与互斥体有何区别?您假设所有进程都将执行lcok,然后执行解锁。但在我的例子中,有些进程只会解锁。我不确定您要完成什么,通常信号量/互斥表示共享资源。如果不知道某件事是否已完成,如何发布/解锁?您所做的听起来更像是POSIX队列。使用文件锁不会减慢进程,因为文件操作会产生不必要的延迟。这里还可以有多个进程,可以执行信号量信号操作。事实上,有些进程只执行信号操作。所以这不是一个典型的互斥操作。感谢您的输入,但我正在寻找一个基于信号量的解决方案,而不是文件锁操作。不,互斥、信号量和文件锁都是在内核中实现的,因为进程需要对它们进行阻塞。锁定文件通常为空,锁定/解锁并不意味着任何I/O。您所描述的语义与互斥体有何区别?您假设所有进程都将执行lcok,然后执行解锁。但在我的例子中,有些进程只会解锁。我不确定您要完成什么,通常信号量/互斥表示共享资源。如果不知道某件事是否已完成,如何发布/解锁?您所做的听起来更像是POSIX队列。