另外,某些应用,如线程池,pthread_cond_broadcast唤醒全部线程,但我们通常只需要一部分线程去做执行任务,所以其它的线程需要继续wait.所以强烈推荐对pthread_cond_wait() 使用while循环来做条件判断.
近期学习了线程等待和激活的相关知识。
先介绍几个api:
pthread_cond_t表示多线程的条件变量,用于控制线程等待和就绪的条件。
一:条件变量的初始化:
条件变量和互斥锁一样,都有静态动态两种创建方式,
静态方式使用PTHREAD_COND_INITIALIZER常量初始化。
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
动态方式初始化:
1 首先要new或者malloc一个pthread_cond_t类型变量,
用完后记得delete或者free掉。
2
使用pthread_cond_wait方式如下:
pthread _mutex_lock(&mutex)
while或if(线程执行的条件是否成立)
pthread_cond_wait(&cond, &mutex);
线程执行
pthread_mutex_unlock(&mutex);
对于这点apue给出的解释:The mutex passed to pthread_cond_wait protects the condition.The caller passes it locked to
the function, which then atomically places the calling thread on the list of threads waiting for the condition and unlocks
the mutex. This closes the window between the time that the condition is checked and the time that the
thread goes to sleep waiting for the condition to change, so that the thread doesn't miss a change in the condition.
When pthread_cond_wait returns, the mutex is again locked.
1,线程放在等待队列上,解锁
2,等待 pthread_cond_signal或者pthread_cond_broadcast信号之后去竞争锁
3,若竞争到互斥索则加锁。
使用流程
等待线程:
pthread_mutex_lock(&mutex);
if(条件不满足)
pthread_cond_wait(&cond, &mutex);
//处理共享资源
pthread_mutex_unlock(&mutex);
激活线程:
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
下面写了一个例子
#include <pthread.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <iostream> using namespace std; int count = 0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; //该函数增加count数值 void * creator(void * arg) { cout << "creator add lock" << endl; pthread_mutex_lock(&mutex); count ++; cout << "in creator count is : " << count << endl; //条件满足时发送信号 if(count > 0) { pthread_cond_signal(&cond); } cout << "creator release lock" << endl; pthread_mutex_unlock(&mutex); return NULL; } //该函数减少count数值 void * consumer(void * arg) { cout << "consumer add lock" << endl; pthread_mutex_lock(&mutex); //当条件不满足时等待 if(count <= 0) { cout << "begin wait" << endl; pthread_cond_wait(&cond,&mutex); cout << "end wait" << endl; } count --; cout << "in consumer count is " << count << endl; pthread_mutex_unlock(&mutex); cout << "consumer release lock" << endl; return NULL; } int main() { //两个线程,一个生产者线程一个消费者线程 pthread_t createthread,consumethread; pthread_create(&consumethread, NULL, consumer, NULL); sleep(2); pthread_create(&createthread, NULL, creator, NULL); //主进程等待两个线程结束 pthread_join(createthread, NULL); pthread_join(consumethread, NULL); return 0; }
void * creator(void * arg) { int i = 0; while(i<300) { i++; cout << "creator add lock" << endl; pthread_mutex_lock(&mutex); count ++; cout << "in creator count is : " << count << endl; if(count > 0) { pthread_cond_signal(&cond); } cout << "creator release lock" << endl; pthread_mutex_unlock(&mutex); } return NULL; } void * consumer(void * arg) { int i = 0; while(i < 100) { i++; cout << "consumer add lock" << endl; pthread_mutex_lock(&mutex); if(count <= 0) { cout << "begin wait" << endl; pthread_cond_wait(&cond,&mutex); cout << "end wait" << endl; } count --; cout << "in consumer count is " << count << endl; pthread_mutex_unlock(&mutex); cout << "consumer release lock" << endl; } return NULL; } int main() { pthread_t createthread[2],consumethread[3]; for(int i = 0; i < 3; i++) { pthread_create(&consumethread[i], NULL, consumer, NULL); } for(int i = 0; i < 2; i++) { pthread_create(&createthread[i], NULL, creator, NULL); } for(int i = 0; i < 2; i++) { pthread_join(createthread[i], NULL); } for(int i = 0; i < 3; i++) { pthread_join(consumethread[i], NULL); } return 0; }
截取一部分结果截图,可以看出数字是连续变动的,而且
加锁解锁内数字才变动,说明我们对锁和条件变量使用合理。
https://blog.csdn.net/hudashi/article/details/7709421
https://www.cnblogs.com/secondtonone1/p/5580203.html