条件变量:
在系统死锁中有这么一个典型的实例:
在一条生产先线上有一个仓库,当生产者生产的时候需要锁住仓库独占,而消费者取产品的时候也要锁住仓库独占。如果生产者发现仓库满了,那么他就不能生产了,变成了阻塞状态。但是此时由于生产者独占仓库,消费者又无法进入仓库去消耗产品,这样就造成了一个僵死状态。
我们需要一种机制,当互斥量被锁住以后发现当前线程还是无法完成自己的操作,那么它应该释放互斥量,让其他线程工作。
1、可以采用轮询的方式,不停的查询你需要的条件
2、让系统来帮你查询条件,使用条件变量pthread_cond_t cond
条件变量使用之前需要初始化
1、pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
2、int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);//默认属性为空NULL
条件变量使用完成之后需要销毁
int pthread_cond_destroy(pthread_cond_t *cond);
条件变量使用需要配合互斥量
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
1、使用pthread_cond_wait等待条件变为真。传递给pthread_cond_wait的互斥量对条件进行保护,调用者把锁住的互斥量传递给函数。
2、这个函数将线程放到等待条件的线程列表上,然后对互斥量进行解锁,这是个原子操作。当条件满足时这个函数返回,返回以后继续对互斥量加锁。
int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);
3、这个函数与pthread_cond_wait类似,只是多一个timeout,如果到了指定的时间条件还不满足,那么就返回。时间用下面的结构体表示
struct timespec{
time_t tv_sec;
long tv_nsec;
};
注意,这个时间是绝对时间。例如你要等待3分钟,就要把当前时间加上3分钟然后转换到 timespec,而不是直接将3分钟转换到 timespec
当条件满足的时候,需要唤醒等待条件的线程
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);
1、pthread_cond_broadcast唤醒等待条件的所有线程
2、pthread_cond_signal至少唤醒等待条件的某一个线程
注意,一定要在条件改变以后在唤醒线程