正确使用POSIX条件变量

来源:互联网 发布:原生js图片上传 编辑:程序博客网 时间:2024/04/29 10:00

最近看到了对于pthread_cond_t条件变量这样的解释:

  • pthread_cond_wait() blocks the calling thread until the specified condition is signalled. This routine should be called while mutex is locked, and it will automatically release the mutex while it waits. After signal is received and thread is awakened, mutex will be automatically locked for use by the thread. The programmer is then responsible for unlocking mutex when the thread is finished with it.

    Recommendation: Using a WHILE loop instead of an IF statement (see watch_count routine in example below) to check the waited for condition can help deal with several potential problems, such as:

    • If several threads are waiting for the same wake up signal, they will take turns acquiring the mutex, and any one of them can then modify the condition they all waited for.
    • If the thread received the signal in error due to a program bug
    • The Pthreads library is permitted to issue spurious wake ups to a waiting thread without violating the standard.
即pthread_cond_wait应该传入一个已经被上锁的mutex互斥量,并且这个互斥量在线程被放到等待条件的线程列表上后会被解锁,在pthread_cond_wait返回的时候互斥量会被再次锁住,这样做的目的是:对于在条件检查和线程进入休眠状态这个之间的时间间隙,条件变量的状态是有可能改变的,所以要等到线程被加入wait队列再释放锁,这样做保证了线程不会错过条件的任何变化.

比如在生产消费者问题中:

while(condd.ready == 1)//已生产,还没消费完,此时producer休眠
   pthread_cond_wait(&condd.cond, &condd.lock);

如果用if,那么100个线程执行这段代码,都被唤醒,后果是每个线程都顺序的认为条件满足了,实际上条件并不满足(生产者生产出来的一件消费品已经被第一个线程消费了)


下面的建议是说:在判断条件是否满足的时候使用while而不是使用if,因为

1 有可能多个线程等待一个条件,而当条件满足时他们去争抢获得mutex,最后只有一个成功锁住mutex,如果使用if那么这些线程都会认为自己条件满足了,但其实是被其他线程抢夺了.

2 有可能因为程序的bug线程获得了信号

3 pthreads库认为虚假的唤醒一个等待线程并不违反标准。


在陈硕的书里这样总结正确使用条件变量:

条件变量只有一种正确使用的方式,几乎不可能用错。对于 wait 端:
1. 必须与 mutex 一起使用,该布尔表达式的读写需受此 mutex 保护。
2. 在 mutex 已上锁的时候才能调用 wait()。
3. 把判断布尔条件和 wait() 放到 while 循环中。

对于 signal/broadcast 端:
1. 不一定要在 mutex 已上锁的情况下调用 signal (理论上)。
2. 在 signal 之前一般要修改布尔表达式。
3. 修改布尔表达式通常要用 mutex 保护(至少用作 full memory barrier)。
4. 注意区分 signal 与 broadcast:“broadcast 通常用于表明状态变化,signal 通常用于表示资源可用。(broadcast should generally be used to indicate state change rather than resource availability。)”


0 0
原创粉丝点击