Chinaunix首页 | 论坛 | 博客
  • 博客访问: 86307
  • 博文数量: 17
  • 博客积分: 318
  • 博客等级: 二等列兵
  • 技术积分: 256
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-07 21:53
文章分类

全部博文(17)

文章存档

2011年(17)

我的朋友

分类: LINUX

2011-11-29 21:00:43

为什么使用条件变量(condition variable

想想我们怎么实现下面的场景:

当线程A需要通知线程B某件事情已经准备好,我们该怎么做?

  我们通常的做法是:设置一个全局变量V,如果线程A已经准备好了某件事,则把V设置为1;线程B则不停得检测V,直到V变为1再继续下面的操作。这种做法的缺点是非常的浪费CPU,因为线程B需要不停的busy loop

  为了改善这种状况,引入了条件变量,它允许一个线程一直休眠,直到另一个线程通知它某件事已经准备好了。顺带提一下,linux内核中有相似的机制semaphore. 

  条件变量是程序用来等待某个谓词为真的机制,也是用来通知其他线程谓词为真的机制。条件变量的作用是发信号(信号代表的具体内容由程序自己解释),而不是互斥,因此程序需要提供一个互斥量来同步对共享数据的访问。

条件变量的初始化

静态初始化

pthread_cond_t cond = PTHREAD_COND_INITIALIZER

动态初始化

int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)


条件变量的销毁

int pthread_cond_destroy(pthread_cond_t *cond)


条件变量的操作

int pthread_cond_signal(pthread_cond_t *cond)

int pthread_cond_broadcast(pthread_cond_t *cond)

注意点:

1.pthread_cond_signal()一次只唤醒一个线程,而pthread_cond_broadcast()唤醒所有等待的线程。

2.条件变量只是一个简单的机制,如果在信号发出后没有线程等待在上面,那么该信号将会丢失。

3.注意pthread_cond_broadcast()调用后,等待线程要完成的工作

       a) 所有的线程都将被唤醒

       b) 首先有一个线程被唤醒,该线程检测共享变量的状态,看是否有工作需要完成。完成相应的工作,改变共享变量的状态用来显示该工作已经完成,释放相应的锁。

       c) 剩下的线程依次的加锁,检测共享变量的状态。因为第一个线程已经改变了共享变量的状态,这些线程发现没有工作需要完成,解锁,然后休眠。

  4.当只有一个线程需要被唤醒来处理改变后的状态时,使用发信号。如果你为多个谓词条件使用一个条件变量,则不能使用发信号操作:因为你不能分辨是应该唤醒等待这个谓词条件的线程,还是唤醒等待那个谓词条件的线程。不要试图通过重发信号绕过去,这可能不会如你所想的传递信号,一个假唤醒或被拦截唤醒可能导致一系列无意义的重发信号--20111130更新


    int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)

    int pthread_cond_timewait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime 

    注意点:

    1.pthread_cond_wait()执行以下原子步骤:

       a)释放mutex

       b)阻塞,直到另一个线程触发了条件变量

       c)再加锁

阅读(2201) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~