我正在Linux上同步读取器和写入器进程。
我有0个或多个进程(读取器)需要在被唤醒之前一直处于睡眠状态,读取资源,然后返回睡眠状态,等等。请注意,我不知道在任何时候有多少个读取器进程在运行。(写入器)在资源上写入,唤醒读取器并执行其操作,直到另一个资源就绪(详细地说,我制定了一个没有饿死读写者的方案,但那并不重要)。
为了实现休眠/唤醒机制,我使用了Posix条件值pthread_cond_t。客户端调用变量上的pthread_cond_wait()来休眠,而服务器执行pthread_cond_broadcast()来唤醒所有客户端。正如手册所述,我用相关pthread互斥锁的锁定/解锁来包围这两个调用。
条件变量和互斥体在服务器中初始化,并通过共享内存区域在进程之间共享(因为我不使用线程,而是使用单独的进程),我确信我的内核/系统调用支持它(因为我检查了_POSIX_THREAD_PROCESS_SHARED)。
当我启动第二个进程时,它阻塞在pthread_cond_wait()上,并且 * 永远 * 不会醒来,即使我(通过日志)确定pthread_cond_broadcast()被调用了。
换句话说,条件变量pthread_cond_broadcast()似乎一次只唤醒一个进程。如果多个进程等待同一个共享条件变量,只有第一个进程能够正确唤醒,而其他进程似乎忽略了广播。
如果我发送一个pthread_cond_broadcast(),* 每个 * 等待进程都应该被唤醒,而不是只有一个(当然,也不总是同一个)。
4条答案
按热度按时间50few1ms1#
是否已在condvar和mutex上设置了
PTHREAD_PROCESS_SHARED
属性?对于Linux,请参阅以下
man
页面:pthread_mutexattr_init
(带样本)pthread_mutexattr_setpshared
pthread_condattr_init
pthread_condattr_setpshared
方法、类型、常量等通常在
/usr/include/pthread.h
、/usr/include/nptl/pthread.h
中定义。t0ybt7op2#
在调用
pthread_cond_wait()
之前,您是否测试了某些条件?我这样问是因为,这是一个非常常见的错误:您的进程 * 不能 * 调用wait()
,除非您知道其他进程 * 稍后 * 将调用signal()
(或broadcast()
)。请考虑以下代码(来自
pthread_cond_wait
手册页):如果你忽略
while
测试,只要你的(x〈= y)条件为真,就从另一个进程发出信号,它不会起作用,因为信号只唤醒已经在等待的进程。如果signal()
在另一个进程调用wait()
之前被调用,信号将丢失,等待的进程将永远等待。编辑:关于while循环。当你从一个进程向另一个进程发送信号时,它被设置在'' ready list ''上,但不一定被调度,并且你的条件(x〈= y)可能会再次改变,因为没有人持有锁。这就是为什么你需要在每次等待时检查你的条件。它应该总是
wakeup -> check if the condition is still true -> do work
。我希望天气晴朗.
oprakyz73#
文档中说它应该可以工作...您确定它与其他线程正在查看的条件值相同吗?
这是opengroup.org中的示例代码:
qlvxas9a4#
最后一张海报说的是正确的。整个cond-variable情况正确工作的关键是cond-var在它被等待之前没有发出信号。它严格地是一个信号,当其他人(一个或多个)在等待时使用。当没有人在等待时,它实际上是一个NOP。顺便说一句,这不是我认为它应该如何工作,而是它如何工作。
拖拉机