7.条件变量简介

来源:互联网 发布:尼尔森数据查询 编辑:程序博客网 时间:2024/04/30 14:54

条件变量,先谈谈自己的理解吧!

互斥量解决了不同线程处理共享资源的问题,比如有俩线程one和two以及和一个共享资源share,one和two每次处理share的前提都是成功获取互斥量mutex,这样的做法保证了共享资源在一段时间里只被一个线程处理,也即保证了处理共享资源的原子性。

但这还不够,常常会有这样的应用需求(mark nb),线程one处理完共享资源share之后,需要通知处于阻塞状态的two线程来接着进行处理。单是互斥量能够解决这样的问题吗?

显然不行,单是使用互斥量,若不计one线程和two线程处理程序的复杂性,那么one线程和two线程处理share的机会是均等的,但是,mark nb这样的应用需求下,明显one线程对共享资源share的占用更有优势。举例,one线程获取共享资源share,two线程把共享资源share处理成share_after:

one thread:  while (1) {  if (ok) {  pthread_mutex_lock(&mutex);  ...// got share  pthread_mutex_unlock(&mutex);  }  }two thread:  while (1) {  pthread_mutex_lock(&mutex);  ...// let share -> share_after  pthread_mutex_unlock(&mutex);  }
这种只是使用到了互斥量的程序设计合格吗?

显然不合格!这样会造成这样的问题产生,线程one还没成功获取到新的share,线程two就已经有机会对“老的”share进行处理了。而事实上,我们需要的one线程每“if (ok)”一次,two才有机会执行一次。

如何能满足这样的需求呢?

条件变量!

关于对条件变量的解释,有文献曰:条件变量是用来通知共享数据的状态信息的机制。

在这种机制下,能够实现这样的功能:线程two平时都是处于阻塞状态,直到线程one在if(ok)中激活它,使它有机会执行一次,下一个while循环又重新处于阻塞状态,等待线程one下一次的“召唤”。

来看看如何用代码完成这样的机制吧!值得一提的是,由于涉及共享数据,因此条件变量是结合互斥量来使用的。

创建和销毁条件变量

POSIX用pthread_cond_t类型的变量来表示条件变量。程序必须在使用pthread_cond_t变量之前对其进行初始化。

对于那些静态分配的、使用默认属性的pthread_cond_t变量来说,可以直接将PTHREAD_COND_INITIALIZER赋给变量就可以完成初始化。如下:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

对那些动态分配的或不使用默认属性的变量来说,就要调用pthread_cond_init函数来进行初始化。该函数的形式为:

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

参数attr是一个条件变量属性对象,如果将NULL传递给attr,则初始化一个具有默认属性的条件变量,否则,就要用与线程属性对象类似的方式,先创建一个条件变量属性对象,再设置它。

函数pthread_cond_destory销毁一个条件变量,该函数的形式为:

int pthread_cond_destory(pthread_cond_t *cond);

暂时就介绍到这里吧,说得再多还不如看看代码示例。

接着可以看后面的文章...

原创粉丝点击