Linux 条件变量函数signal和wait补充

pthread_cond_wait必须放在pthread_mutex_lock和pthread_mutex_unlock之间
因为他要根据共享变量的状态来觉得是否要等待,而为了不永远等待下去所以必须要在lock/unlock中
共享变量的状态改变必须遵守lock/unlock的规则

pthread_cond_signal即可以放在pthread_mutex_lock和pthread_mutex_unlock之间,
也可以放在pthread_mutex_lock和pthread_mutex_unlock之后,但是各有有缺点。

pthread_mutex_lock(&mutex);  
  
// 修改共享数据...  
  
// 通知等待的线程,条件已经改变  
pthread_cond_signal(&cond); // 或 pthread_cond_broadcast(&cond) 如果需要唤醒所有等待的线程  
  
// 释放互斥锁,以便其他线程可以获取它  
pthread_mutex_unlock(&mutex);

缺点:可能存在性能损耗。
当A线程执行 pthread_cond_signal 唤醒B线程 pthread_cond_wait 函数,
B线程立即苏醒,开始执行 pthread_mutex_lock ,但是此时A线程还没有执行 pthread_mutex_unlock,B线程阻塞;
A线程执行 pthread_mutex_unlock 函数,B线程继续往下执行。

 

pthread_mutex_lock(&mutex);  
  
// 修改共享数据...  
  
// 释放互斥锁,以便其他线程可以获取它  
pthread_mutex_unlock(&mutex);

// 通知等待的线程,条件已经改变  
pthread_cond_signal(&cond); // 或 pthread_cond_broadcast(&cond) 如果需要唤醒所有等待的线程 

优点:不会出现之前说的那个潜在的性能损耗,因为在signal之前就已经释放锁了
缺点:如果unlock在signal之前,有个低优先级的线程正在mutex上等待的话,
那么这个低优先级的线程就会抢占高优先级的线程(cond_wait的线程),
而这在上面的放中间的模式下是不会出现的。

 

Linux内核优化:
Linux内核中维持着cond_wait队列和mutex_lock队列,pthread_cond_signal 会让B线程直接从cond_wait队列移到mutex_lock队列,
避免返回用户空间,从而性能得到提升

 

posted on 2018-09-22 09:39  寒魔影  阅读(554)  评论(0编辑  收藏  举报

导航