7.3.4条件变量的销毁
int pthread_cond_destroy(pthread_cond_t *cond);
注意:
1、永远不要用一个条件变量对另一个条件变量赋值, 即pthread_cond_t cond_b = cond_a不合法, 这种行为是未定义的。
2、使用PTHREAD_COND_INITIALIZE静态初始化的条件变量, 不需要被销毁。
3、要调用pthread_cond_destroy销毁的条件变量可以调用pthread_cond_init重新进行初始化。
4、不要引用已经销毁的条件变量, 这种行为是未定义的。
例:
#include
#include #include #include #include #define NUMBER 2int g_bowl = 0;pthread_mutex_t mutex;//定义互斥锁pthread_cond_t cond1;//条件变量pthread_cond_t cond2;//条件变量void *WorkProduct(void *arg){ int *p = (int*)arg; while(1) { pthread_mutex_lock(&mutex); while(*p > 0) { pthread_cond_wait(&cond2,&mutex);//条件等待,条件不满足,陷入阻塞 } ++(*p); printf("i am workproduct :%d,i product %dn",(int)syscall(SYS_gettid),*p); pthread_cond_signal(&cond1);//通知消费者 pthread_mutex_unlock(&mutex);//释放锁 } return NULL;}void *WorkConsume(void *arg){ int *p = (int*)arg; while(1) { pthread_mutex_lock(&mutex); while(*p <= 0) { pthread_cond_wait(&cond1,&mutex);//条件等待,条件不满足,陷入阻塞 } printf("i am workconsume :%d,i consume %dn",(int)syscall(SYS_gettid),*p); --(*p); pthread_cond_signal(&cond2);//通知生产者 pthread_mutex_unlock(&mutex);//释放锁 } return NULL;}int main(){ pthread_t cons[NUMBER],prod[NUMBER]; pthread_mutex_init(&mutex,NULL);//互斥锁初始化 pthread_cond_init(&cond1,NULL);//条件变量初始化 pthread_cond_init(&cond2,NULL);//条件变量初始化 int i = 0; for(;i < NUMBER;++i) { int ret = pthread_create(&prod[i],NULL,WorkProduct,(void*)&g_bowl); if(ret != 0) { perror("pthread_create"); return -1; } ret = pthread_create(&cons[i],NULL,WorkConsume,(void*)&g_bowl); if(ret != 0) { perror("pthread_create"); return -1; } } for(i = 0;i < NUMBER;++i) { pthread_join(cons[i],NULL);//线程等待 pthread_join(prod[i],NULL); } pthread_mutex_destroy(&mutex);//销毁互斥锁 pthread_cond_destroy(&cond1); pthread_cond_destroy(&cond2); while(1) { printf("i am main work threadn"); sleep(1); } return 0;}
在这里为什么有两个条件变量呢?
若所有的线程只使用一个条件变量,会导致所有线程最后都进入PCB等待队列。
thread apply all bt查看:

7.3.5情况分析:两个生产者,两个消费者,一个PCB等待队列
1、最开始的情况,两个消费者抢到了锁,此时生产者未生产,则都放入PCB等待队列中

2、一个生产者抢到了锁,生产了一份材料,唤醒一个消费者,此时三者抢锁,若两个生产者分别先后抢到了锁,则都进入PCB等待队列中

3、只有一个消费者,则必会抢到锁,消费材料,唤醒PCB等待队列,若此时唤醒的是,消费者,则现在是这样一个情况:

4、两个消费者在外边抢锁,一定都会进入PCB等待队列中

解决上述问题可采用两种方法:
1、使用int pthread_cond_broadcast(pthread_cond_t *cond);,唤醒PCB等待队列中所有的线程。此时所有线程都会同时执行抢锁逻辑,太消费资源了。此方法不妥
2、采用两个PCB等待序列,一个放生产者,一个放消费者,生产者唤醒消费者,消费者唤醒生产者。