条件变量
1. 函数原型:
pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
分析:
- 函数作用:阻塞等待一个条件变量
- 阻塞等待条件变量cond(参数1)满足
- 释放已掌握的互斥锁(解锁互斥量),相当于pthread_mutex_unlock(&mutex); {1、2两步为一个原子操作}
- 当被唤醒,pthread_cond_wait函数返回,解除阻塞并重新获取互斥锁pthread_mutex_lock。
1. 示例
1 #include <pthread.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <stdio.h> 5 6 struct msg 7 { 8 struct msg *next; 9 int num; 10 }; 11 12 struct msg *head; 13 struct msg *mp; 14 15 pthread_cond_t has_product = PTHREAD_COND_INITIALIZER; //静态初始化:一个条件变量和一个互斥量 16 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 17 18 void *consumer(void *p) 19 { 20 for (; ;) 21 { 22 pthread_mutex_lock(&lock); 23 while (head == NULL) //头指针为空,说明没有节点 可以为if吗 24 pthread_cond_wait(&has_product, &lock); 25 mp = head; 26 head = mp->next; //模拟消费掉一个产品 27 pthread_mutex_unlock(&lock); 28 printf("-consume-----%d\n", mp->num); 29 free(mp); 30 sleep(rand() % 5); 31 } 32 } 33 34 void *producer(void *p) 35 { 36 for (; ;) 37 { 38 mp = malloc(sizeof(struct msg)); 39 mp->num = rand() % 1000 + 1; //模拟生产一个产品 40 printf("-Produce----%d\n", mp->num); 41 42 pthread_mutex_lock(&lock); 43 mp->next = head; 44 head = mp; 45 pthread_mutex_unlock(&lock); 46 47 pthread_cond_signal(&has_product); //将等待在该条件变量上的一个线程唤醒 48 sleep(rand() % 5); 49 } 50 } 51 52 int main() 53 { 54 pthread_t pid, cid; 55 srand(time(NULL)); 56 pthread_create(&pid, NULL, producer, NULL); 57 pthread_create(&cid, NULL, consumer, NULL); 58 pthread_join(pid, NULL); 59 pthread_join(cid, NULL); 60 return 0; 61 }
2. 示例
1 #include <iostream> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <pthread.h> 5 using namespace std; 6 7 struct 8 { 9 int t; 10 pthread_mutex_t mutex; 11 pthread_cond_t cond; 12 } test = {0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER}; 13 14 void *Print(void *a) 15 { 16 int num = *(int *)a; 17 for (int i = 0; i < 5; ++i) 18 { 19 pthread_mutex_lock(&test.mutex); 20 21 while (num != test.t) 22 pthread_cond_wait(&test.cond, &test.mutex); 23 24 cout << pthread_self() << ": " << static_cast<char>('A' + num) << endl; 25 test.t = (test.t + 1) % 5; 26 pthread_mutex_unlock(&test.mutex); 27 pthread_cond_broadcast(&test.cond); 28 } 29 } 30 31 int main() 32 { 33 pthread_t t[5]; 34 for (int i = 0; i < 5; ++i) 35 { 36 int *a = (int *)malloc(sizeof(int)); 37 *a = i; 38 pthread_create(&t[i], NULL, Print, (void *)a); 39 } 40 for (int i = 0; i < 5; ++i) 41 { 42 pthread_join(t[i], NULL); 43 } 44 return EXIT_SUCCESS; 45 }