条件变量
条件变量是利用线程间共享的"全局变量"进行同步的一种机制,主要包括两个动作:
1、线程等待"条件变量的条件成立"而休眠;
2、等"条件成立"叫醒休眠的线程。
为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起,一般线程睡入条件变量,伴随着解锁动作,而线程从条件变量醒来时,伴随着加锁动作,如果加锁失败线程进入阻塞状态,而不是睡眠。
// 定义或创建条件变量 pthread_cond_t cond; // 初始化条件变量 int pthread_cond_init (pthread_cond_t* cond,const pthread_condattr_t* attr); //亦可pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // 使调用线程睡入条件变量cond,同时释放互斥锁mutex int pthread_cond_wait (pthread_cond_t* cond,pthread_mutex_t* mutex); // 带倒计时的睡眠,时间到了会自动醒来 int pthread_cond_timedwait (pthread_cond_t* cond, pthread_mutex_t* mutex, const struct timespec* abstime); struct timespec { time_t tv_sec; // Seconds long tv_nsec; // Nanoseconds [0 - 999999999] }; // 从条件变量cond中叫醒一个线程,令其重新获得原先的互斥锁 int pthread_cond_signal (pthread_cond_t* cond); 注意:被唤出的线程此刻将从pthread_cond_wait函数中返回, 但如果该线程无法获得原先的锁,则会继续阻塞在加锁上。 // 从条件变量cond中唤醒所有线程 int pthread_cond_broadcast (pthread_cond_t* cond); // 销毁条件变量 int pthread_cond_destroy (pthread_cond_t* cond);
注意:使用互斥锁配合条件变量实现的生产者与消费者模型,能够平衡生产与消费的时间不协调,并且可以最大限度的节约运行资源。
#include <stdio.h> #include <unistd.h> #include <pthread.h> pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void* run(void* arg) { int index = 1; for(;;) { pthread_mutex_lock(&mutex); if(0 == index % 10) { printf("任务已完成,即将睡眠!\n"); pthread_cond_wait(&cond,&mutex); } printf("index = %d\n",index++); sleep(1); pthread_mutex_unlock(&mutex); } } int main(int argc,const char* argv[]) { pthread_t tid; pthread_create(&tid,NULL,run,NULL); printf("是否叫醒睡眠的线程?"); for(;;) { char cmd = getchar(); if('y' == cmd) { pthread_cond_signal(&cond); } } pthread_join(tid,NULL); return 0; }