条件变量是线程可用的另一种同步机制。条件变量用于自动壅闭线程,知道某个特定事件发生或某个条件满足为止,通常情况下,条件变量是和互斥锁一起搭配利用的。利用条件变量重要包括两个动作:
- 一个线程等待某个条件满足而被壅闭;
- 另一个线程中,条件满足时发出“信号”。
为了阐明这个标题,来看一个没有利用条件变量的例子,生产者---消费者模式,生产者这边负责生产产品、而消费者负责消费产品,对于消费者来说,没有产品的时候只能等待产品出来,有产品就利用它。这里我们利用一个变量来表现这个这个产品,生产者生产一件产品变量加 1,消费者消费一次变量减 1,
示例代码如下所示:
- //示例代码 12.3.1 生产者---消费者示例代码
- #include <stdio.h>
- #include <stdlib.h>
- #include <pthread.h>
- #include <unistd.h>
- #include <string.h>
- static pthread_mutex_t mutex;
- static int g_avail = 0;
- /* 消费者线程 */
- static void *consumer_thread(void *arg)
- {
- for ( ; ; ) {
- pthread_mutex_lock(&mutex);//上锁
- while (g_avail > 0)
- g_avail--; //消费
- pthread_mutex_unlock(&mutex);//解锁
- }
- return (void *)0;
- }
- /* 主线程(生产者) */
- int main(int argc, char *argv[])
- {
- pthread_t tid;
- int ret;
- /* 初始化互斥锁 */
- pthread_mutex_init(&mutex, NULL);
- /* 创建新线程 */
- ret = pthread_create(&tid, NULL, consumer_thread, NULL);
- if (ret) {
- fprintf(stderr, "pthread_create error: %s\\n", strerror(ret));
- exit(-1);
- }
- for ( ; ; )
- {
- pthread_mutex_lock(&mutex);//上锁
- g_avail++; //生产
- pthread_mutex_unlock(&mutex);//解锁
- }
- exit(0);
- }
复制代码 此代码中,主线程作为“生产者”,新创建的线程作为“消费者”,运行之后它们都回处于死循环中,所以代码中没有加入销毁互斥锁、等待回收新线程相关的代码,历程终止时会自动被处理。
上述代码固然可行,但由于新线程中会不停的循环检查全局变量 g_avail 是否大于 0,故而造成 CPU 资源的浪费。采用条件变量这一标题就可以迎刃而解!条件变量允许一个线程休眠(壅闭等待)直至获取到另一个线程的关照(收到信号)再去实行自己的操纵,譬如上述代码中,当条件 g_avail > 0 不建立时,消费者线程会进入休眠状态,而生产者生成产品后(g_avail++,此时 g_avail 将会大于 0),向处于等待状态的线程发出“信号”,而别的线程收到“信号”之后,便会被叫醒!
|