当前位置:  技术问答>linux和unix

pthread_cond_wait的一个迷惑

    来源: 互联网  发布时间:2016-04-25

    本文导语:            pthread_mutex_lock( &qlock ); while( /*判断条件*/ ) { pthread_cond_wait( &qready , &qlock ); } 调用pthread_cond_signal发送信号,唤醒线程,既然都唤醒线程了,应该就是条件成立了阿,为什么还要在循环中判断一次是否条...

 
        pthread_mutex_lock( &qlock );
while( /*判断条件*/ )
{
pthread_cond_wait( &qready , &qlock );
}


调用pthread_cond_signal发送信号,唤醒线程,既然都唤醒线程了,应该就是条件成立了阿,为什么还要在循环中判断一次是否条件成立呢??

我在网上搜到这样一段话,不是很明白
“您会注意到这个调用在一个非常紧凑的 while() 循环中,这是非常重要的。当从 pthread_cond_wait() 调用中苏醒时,决不能认为条件肯定发生了 -- 它 可能发生了,也可能没有发生。如果发生了这种情况,即错误地唤醒了线程,而列表是空的,那么 while 循环将再次调用 pthread_cond_wait()。“
这里说”错误的唤醒了线程“指的是那种情况呢?? 如果说是程序员本身错误的在条件未成立的时候唤醒了线程,那应该是代码的问题,那么还有一个情况就是系统有可能会唤醒线程吗?在没有调用pthread_cond_signal的时候。 



|
我来说一下,大家拍砖! 要明白其中道理,就要明白pthread_cond_wait()具体是如何实现的,如果将pthread_cond_wait()分解的话,可以看作如下三步:

# Step 1:解锁; 
# Step 2: 等待信号 (等待pthread_cond_signal,pthread_cond_broadcast的信号);
# Step 3: 加锁; 

下面来看看这段代码:

  pthread_mutex_lock();
  while(condition_is_false)
     pthread_cond_wait();
  pthread_mutex_unlock();

分解一下,其实就基本上等价于如下代码:


  pthread_mutex_lock();       //1
  while(condition_is_false)
  {
     pthread_mutex_unlock();  //2
     等待信号;
     pthread_mutex_lock();    //3
  }
  pthread_mutex_unlock();     //4


可以看出,pthread_cond_wait();不是原子操作;如果有两个线程等待在同一个条件变量上(一个生产者,两个消费者的情况),记消费者为:A,B;那么都有类似上面一段代码;那么可能的一种情况是:
A执行到2处的pthread_mutex_unlock();这句话之后,由于锁此时已经解开,那么B可能获得锁,执行1处代码,然后也进入到了pthread_cond_wait();的执行;然后执行4处的解锁,然后把资源消耗掉了! 之后,A继续执行,也从pthrea_cond_wait()返回了,可是此时资源却被B抢走了,没有资源可用了,所以要在判断一下条件,看是否继续等待!

凑合者看,大概就这意思,可能描述不是很清楚!

good luck! 


|

引用下POSIX的RATIONALE:

    Condition Wait Semantics

    It is important to note that when pthread_cond_wait() and pthread_cond_timedwait() return without error, the associated predicate may still be false. Similarly, when pthread_cond_timedwait() returns with the timeout error, the associated predicate may be true due to an unavoidable race between the expiration of the timeout and the predicate state change.

    The application needs to recheck the predicate on any return because it cannot be sure there is another thread waiting on the thread to handle the signal, and if there is not then the signal is lost. The burden is on the application to check the predicate.

    Some implementations, particularly on a multi-processor, may sometimes cause multiple threads to wake up when the condition variable is signaled simultaneously on different processors.

    In general, whenever a condition wait returns, the thread has to re-evaluate the predicate associated with the condition wait to determine whether it can safely proceed, should wait again, or should declare a timeout. A return from the wait does not imply that the associated predicate is either true or false.

    It is thus recommended that a condition wait be enclosed in the equivalent of a "while loop" that checks the predicate.

从上文可以看出:
1,pthread_cond_signal在多处理器上可能同时唤醒多个线程,当你只能让一个线程处理某个任务时,其它被唤醒的线程就需要继续wait,while循环的意义就体现在这里了,而且规范要求pthread_cond_signal至少唤醒一个pthread_cond_wait上的线程,其实有些实现为了简单在单处理器上也会唤醒多个线程.
2,某些应用,如线程池,pthread_cond_broadcast唤醒全部线程,但我们通常只需要一部分线程去做执行任务,所以其它的线程需要继续wait.
   所以强烈推荐此处使用while循环

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 关于pthread_cond_wait的几个问题
  • pthread_attr_init()及pthread_cond_wait使用疑惑
  • pthread_cond_signal和pthread_cond_wait两个函数是怎么意思?
  • ~如何GDB调试因pthread_cond_wait()阻塞的线程??~
  • pthread_cond_wait 不阻塞?
  • 关于pthread_cond_wait函数
  • pthread_cancel和pthread_cond_wait
  • 关于pthread_cond_wait的一个简单问题!
  • pthread_cond_wait 之前的 pthread_mutex_lock 语句 有什么作用,可以不用吗?
  • pthread_cond_wait 没起作用?
  • 线程广播信号,pthread_cond_wait却仍在等待。
  • pthread_cond_wait() 用法深入分析


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3