条件变量
1. 条件变量初始化
1 // 方法1 2 pthread_cond_t cv = PTHREAD_COND_INITIALIZER; 3 4 5 // 方法2 6 pthread_cond_t cv; 7 pthread_condattr_t cattr; 8 int ret; 9 10 /* initialize a condition variable to its default value */ 11 ret = pthread_cond_init(&cv, NULL); 12 13 14 // 条件变量其实可以有属性,但是一般忽略,Linux中也没有实现 15 /* initialize a condition variable */ 16 ret = pthread_cond_init(&cv, &cattr);
2. 条件变量注销
int pthread_cond_destroy(pthread_cond_t *cv);
注意:条件变量注销后,并没有释放用户储存条件变量的空间
只有在没有线程在该条件变量上等待的时候才能注销这个条件变量,否则返回EBUSY。
因为linux实现的条件变量没有分配什么资源,所以注销动作只包括检查是否有等待线程。
3. 基于条件变量阻塞
int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex);
如果条件变量cv没有满足,pthread_cond_wait()就会释放锁+阻塞,等待唤醒;
唤醒之后,pthread_cond_wait()首先会拿到锁,然后就没有然后了,函数完成,继续往下走!
① pthread_cond_wait()要与互斥锁一起使用,即在互斥锁的保护下使用,因为该函数有一个释放锁步骤
—— 这是我理解的使用锁的原因,目前没有找到更有说服力的,待求证???
② pthread_cond_wait()建议与while()一起使用
pthread_mutex_lock(); while(condition_is_false) pthread_cond_wait(); pthread_mutex_unlock();
官方给出的解释是:
唤醒的线程重新获取互斥锁并从 pthread_cond_wait() 返回之前,条件可能会发生变化,等待线程可能并未真正唤醒。
建议使用的测试方法是,将条件检查编写为调用 pthread_cond_wait() 的 while() 循环。
链接给出了一个很好的例子,可以尝试练习:生产者和使用者问题
https://docs.oracle.com/cd/E19253-01/819-7051/sync-83092/index.html