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队列。