问题描述
我学习的pthread,等待条件。至于我可以告诉一个典型的等待线程是这样的:
的pthread_mutex_lock(安培; M);
而(!条件)
调用pthread_cond_wait(安培; COND,&放大器;米);
//线程的东西在这里
调用pthread_mutex_unlock(安培;米);
我不明白的是为什么行而(!条件)
是必要的,即使我用调用pthread_cond_signal()
来唤醒线程。
我可以理解,如果我使用调用pthread_cond_broadcast()
我需要测试的条件,因为我醒来的所有的等待线程,其中一个可以解锁互斥(因此转移到执行,不应该在这一点上执行其他唤醒线程)之前,再次使病情假的。
但是,如果使用调用pthread_cond_signal()
我醒来刚刚的有一个的线程,这样的情况必须是真实的。因此,code可能是这样的:
的pthread_mutex_lock(安培; M);
调用pthread_cond_wait(安培; COND,&放大器;米);
//线程的东西在这里
调用pthread_mutex_unlock(安培;米);
我读了一些关于可能发生的杂散信号。这是(也只有这个)的原因是什么?为什么我应该有虚假singnals?或者还有别的东西我不明白?
我假定信号code是这样的:
的pthread_mutex_lock(安培; M);
条件=真;
调用pthread_cond_signal(安培; COND); //应该唤醒*一*线程
调用pthread_mutex_unlock(安培;米);
你应该把调用pthread_cond_wait在循环的真正原因是不是虚假唤醒的原因。即使你的条件变量没有虚假唤醒,你仍然需要循环捕捉错误的一种常见类型。为什么?试想,如果多个线程等待相同的条件下会发生什么:
线程1线程2线程3
检查条件(失败)
(在cond_wait)解锁互斥
(在cond_wait)等
互斥锁
设置条件
信号condvar
解锁互斥
互斥锁
检查状态(成功)
做东西
未设置条件
解锁互斥
(在cond_wait)醒来
(在cond_wait)互斥锁
<螺纹是清醒的,但条件
未设置>
这里的问题是,该线程必须等待之前释放互斥体,可能允许另一个线程来偷无论该线程在等待。除非它是保证只有一个线程可以等待在此条件下,是不正确的假设条件下是有效的,当一个线程被唤醒。
I'm learning pthread and wait conditions. As far as I can tell a typical waiting thread is like this:
pthread_mutex_lock(&m);
while(!condition)
pthread_cond_wait(&cond, &m);
// Thread stuff here
pthread_mutex_unlock(&m);
What I can't understand is why the line while(!condition)
is necessary even if I use pthread_cond_signal()
to wake up the thread.
I can understand that if I use pthread_cond_broadcast()
I need to test condition, because I wake up all waiting threads and one of them can make the condition false again before unlocking the mutex (and thus transferring execution to another waked up thread which should not execute at that point).But if I use pthread_cond_signal()
I wake up just one thread so the condition must be true. So the code could look like this:
pthread_mutex_lock(&m);
pthread_cond_wait(&cond, &m);
// Thread stuff here
pthread_mutex_unlock(&m);
I read something about spurious signals that may happen. Is this (and only this) the reason? Why should I have spurious singnals? Or there is something else I don't get?
I assume the signal code is like this:
pthread_mutex_lock(&m);
condition = true;
pthread_cond_signal(&cond); // Should wake up *one* thread
pthread_mutex_unlock(&m);
The real reason you should put pthread_cond_wait in a while loop is not because of spurious wakeup. Even if your condition variable did not have spurious wakeup, you would still need the loop to catch a common type of error. Why? Consider what can happen if multiple threads wait on the same condition:
Thread 1 Thread 2 Thread 3
check condition (fails)
(in cond_wait) unlock mutex
(in cond_wait) wait
lock mutex
set condition
signal condvar
unlock mutex
lock mutex
check condition (succeeds)
do stuff
unset condition
unlock mutex
(in cond_wait) wake up
(in cond_wait) lock mutex
<thread is awake, but condition
is unset>
The problem here is that the thread must release the mutex before waiting, potentially allowing another thread to 'steal' whatever that thread was waiting for. Unless it is guaranteed that only one thread can wait on that condition, it is incorrect to assume that the condition is valid when a thread wakes up.
这篇关于Pthread的等待条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!