是否可以仅使用 POSIX 信号量来避免唤醒等待竞赛?是良性的吗?
Posted
技术标签:
【中文标题】是否可以仅使用 POSIX 信号量来避免唤醒等待竞赛?是良性的吗?【英文标题】:Is it possible to avoid a wakeup-waiting race using only POSIX semaphores? Is it benign? 【发布时间】:2008-12-10 03:48:34 【问题描述】:我想使用 POSIX 信号量来管理代表队列的文件中的原子获取和放置。我想要在文件系统中命名某些东西的灵活性,以便完全不相关的进程可以共享一个队列。我认为这个计划排除了 pthreads。命名的 posix 信号量非常适合在文件系统中放入任何进程都可以看到的东西,但我找不到标准的 CondWait 原语:
... decide we have to wait ....
CondWait(sem, cond);
当进程调用 CondWait 时,它会自动发布到 sem 并等待 cond。当其他一些进程发布到 cond 时,等待进程只有在它也可以自动递减 sem 时才会唤醒。的替代品
... decide we have to wait ....
sem_post(sem);
sem_wait(cond);
sem_wait(sem);
受制于竞争条件,其中一些其他进程在此进程等待它之前发出 cond 信号。
我几乎没有做过任何并发编程,所以我想我会问:如果我使用标准的 POSIX 计数信号量作为条件变量,这种竞争是否可能是良性的?
以防万一有人想要更大的上下文,我正在为可以从 shell 脚本调用的原子队列构建 get 和 put 操作。
【问题讨论】:
【参考方案1】:由于没有其他答案,我将跟进我所学到的:
Pthreads 不适用于我的应用程序,因为我的进程没有共同的祖先,需要共享原子队列。 Posix 信号量受制于唤醒等待竞争,但由于与经典条件变量不同它们计数信号量,竞争是良性的。我没有这种说法的证据,但我的系统已经运行了两天并且运行良好。 (我知道这完全没有意义,但至少这意味着我完成了工作。) 命名 Posix 信号量难以从文件系统中进行垃圾收集。总而言之,命名 Posix 信号量被证明是实现原子队列抽象以在不相关进程之间共享的良好基础。
我想要一个证明或经过验证的 SPIN 模型,但由于我对该应用程序的需求有限,我似乎不太可能编写一个。我希望这对可能想要使用 Posix 信号量的其他人有所帮助。
【讨论】:
【参考方案2】:根据POSIX 标准,信号量例程的集合是:
sem_close() sem_destroy() sem_getvalue() sem_init() sem_open() sem_post() sem_timedwait() sem_trywait() sem_unlink() sem_wait()sem_trywait()
和 sem_timedwait()
函数可能正是您想要的。
【讨论】:
它们都是有用的函数,但是为了确定是否存在竞争条件,它们可以被视为与 sem_wait() 相同。我相信有一场比赛,但因为 POSIX 信号量正在计算信号量,所以比赛是良性的。【参考方案3】:我知道这个问题很老,但显而易见的解决方案是只使用位于文件中的进程共享互斥锁和条件变量mmap
。
【讨论】:
你错过了我回答的最后 6 个字吗? 您可以在文件中mmap
。如果你这样做,当然不相关的进程可以共享它。他们只是mmap
它。
我确实错过了你答案的最后六个字。【参考方案4】:
您正在寻找:pthread_cond_wait,pthread_cond_signal,我想。 也就是说,如果您使用的是 posix 线程,那么 pthread 方法将提供 CondWait 和 Signal 的功能。 通过共享内存在此处查找有关多进程 pthread 的源代码。http://linux.die.net/man/3/pthread_mutexattr_init 那是针对 Linux 的,但文档是 posix 的。它们类似于 Solaris,但您需要仔细阅读操作系统上的手册页。
【讨论】:
您能否解释一下,在init 之外不共享共同祖先的多个进程如何实现这一点?我认为pthreads都必须由同一个进程启动。不容易适应 shell 脚本。以上是关于是否可以仅使用 POSIX 信号量来避免唤醒等待竞赛?是良性的吗?的主要内容,如果未能解决你的问题,请参考以下文章