是否保证pthread_cond_信号将唤醒正在等待的线程?
这是一个一般性问题。例如,当前有两个子线程调用了是否保证pthread_cond_信号将唤醒正在等待的线程?,c,pthreads,condition-variable,C,Pthreads,Condition Variable,这是一个一般性问题。例如,当前有两个子线程调用了pthread\u cond\u wait(&cond1,&mutex),它们都在等待。然后,父线程调用 pthread_cond_signal(&cond1); pthread_cond_signal(&cond1); 接下来,我的问题是,是否保证两个等待的线程都会被唤醒?(假设被唤醒的第一个线程稍后在执行的某个阶段释放互斥,以便第二个线程可以获取互斥) 我问这个问题的原因是,对于Unix系统级信号,信号(比如说SIGCHLD)
pthread\u cond\u wait(&cond1,&mutex)
,它们都在等待。然后,父线程调用
pthread_cond_signal(&cond1);
pthread_cond_signal(&cond1);
接下来,我的问题是,是否保证两个等待的线程都会被唤醒?(假设被唤醒的第一个线程稍后在执行的某个阶段释放互斥,以便第二个线程可以获取互斥)
我问这个问题的原因是,对于Unix系统级信号,信号(比如说
SIGCHLD
)没有排队,因此如果连续发送,相同类型的多个信号可能会丢失。因此,我想知道pthread\u cond\u signal
是否以不同的方式实现,以便在调度程序让父线程连续发出两次信号时不会丢失它们?快速回答:
pthread\u cond\u signal()
将唤醒至少一个在条件变量上被阻止的线程,但不能保证唤醒的线程超过此数目(参考,请使用pthread\u cond\u broadcast()
唤醒所有被阻止的线程)
发件人:
pthread_cond_signal()调用至少取消阻止一个线程
在指定的条件变量cond(如果有)上被阻止的
线程在cond上被阻塞
pthread_cond_broadcast()调用当前取消阻止所有线程
在指定的条件变量cond上被阻止
较长的答案:
因此,根据规范,我假设解除阻塞是同步发生的,也就是说,通过第一次调用pthread\u cond\u signal()
解除阻塞的线程将被第二次调用pthread\u cond\u signal()
解除阻塞,从而唤醒另一个线程
但是,我不知道您的特定pthread实现是否是这样(而且glibc网站目前非常危险,因此无法访问代码查看)
可能尚未实现,但它在规范答案中:
但是应该注意的是,该规范最近稍微修改了一下,pthread\u cond\u signal()
和pthread\u cond\u broadcast()
如何确定在给定条件变量上实际阻塞了哪些线程,但我认为并非所有的实现都能跟上
可以找到关于该主题的长期讨论,新规范为:
pthread_cond_broadcast()和pthread_cond_signal()函数
应自动确定堵塞的螺纹(如有)
在指定的条件变量cond上。这个决心
应在试验期间的未指定时间发生
pthread_cond_broadcast()或pthread_cond_signal()调用。
pthread_cond_broadcast()函数随后将解除对所有
这些线。pthread_cond_signal()函数应在
这些线程中至少有一个
因此,结论是:
如果不是规范的专家解释者,我会说新的文本支持这种同步发生的假设——这样两个连续调用pthread\u cond\u signal()
并有两个阻塞线程可用,就会唤醒两个线程
不过,我不是100%确定,所以如果有人能详细说明,请尽管这样做。我知道这是一个古老的线程(没有双关语),但典型的实现是这样工作的: 一个条件变量将包含一个当前处于休眠状态的线程队列,等待它收到信号 锁将有一个线程队列,这些线程已进入睡眠状态,因为它们试图获取它,但被另一个线程持有 cond_wait将正在运行的线程添加到条件变量的队列中,释放锁,并将其自身置于睡眠状态 cond_信号只是将一个休眠线程从条件变量的队列移动到锁的队列 当运行线程释放锁时,将从锁的队列中移除一个休眠线程,锁的所有权转移到该休眠线程,并唤醒该休眠线程
不要问我为什么规范会说cond_信号可能会唤醒多个线程…查看
pthread_cond_信号()
实现,有一条注释简要解释了代码的作用:
加载服务员序列号,它表示我们对任何服务员的相对顺序。放松的MO足以满足这一要求,因为:
\u pthread\u cond\u wait
呼叫,该服务员必须有资格被我们叫醒。唯一的方法是在获取与condvar
相关联的互斥量的同时发送信号,并确保信号的关键部分发生在等待之后。因此,互斥锁确保我们看到服务员的\uuuwseq
增加pthread\u cond\u wait()
实现中有关于该算法的更多信息:
这个condvar
实现保证了对信号和广播的所有调用,以及对
pthread_mutex_lock(mutex);
...
pthread_cond_signal(cond1); // no mutex reference, these calls could happen
pthread_cond_signal(cond1); // while the mutex is not locked...
pthread_cond_unlock(mutex);
pthread_mutex_lock(mutex);
...
pthread_cond_wait(cond1, mutex);
...
pthread_mutex_unlock(mutex);
#define __PTHREAD_COND_MAX_GROUP_SIZE ((unsigned) 1 << 29)