pthread_cond_broadcast & pthread_cond_signal
作者:互联网
pthread_cond_broadcast(&cond1)的作用是唤醒所有正在pthread_cond_wait(&cond1,&mutex1)的线程。
pthread_cond_signal(&cond1)的的作用是唤醒所有正在pthread_cond_wait(&cond1,&mutex1)的其中一个线程。
下面分为情况讨论一下这两个函数的效果。
第一种情况:多个线程等待同一个cond,并且想对同一个mutex加锁。
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <pthread.h> 4 #include <stdlib.h> 5 6 pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 7 pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; 8 9 void* thread_task1(void* arg) 10 { 11 pthread_mutex_lock(&mutex1); 12 13 pthread_cond_wait(&cond,&mutex1); 14 15 printf("thread_task1 start working\n"); 16 sleep(2); 17 printf("thread_task1 works over\n"); 18 pthread_mutex_unlock(&mutex1); 19 20 return NULL; 21 22 23 } 24 25 void* thread_task2(void* arg) 26 { 27 pthread_mutex_lock(&mutex1); 28 29 pthread_cond_wait(&cond,&mutex1); 30 31 printf("thread_task2 start working\n"); 32 sleep(2); 33 printf("thread_task2 works over\n"); 34 pthread_mutex_unlock(&mutex1); 35 36 return NULL; 37 38 } 39 40 void* broadcastSameMutex(void* arg) 41 { 42 pthread_cond_broadcast(&cond); 43 return NULL; 44 } 45 46 void* signalSameMutex(void* arg) 47 { 48 pthread_cond_signal(&cond); 49 return NULL; 50 } 51 52 int main() 53 { 54 pthread_t thread_1,thread_2,thread_3; 55 pthread_create(&thread_1,NULL,thread_task1,NULL); 56 pthread_create(&thread_2,NULL,thread_task2,NULL); 57 sleep(2); 58 59 #ifdef SIGNAL 60 pthread_create(&thread_3,NULL,signalSameMutex,NULL); 61 #else 62 pthread_create(&thread_3,NULL,broadcastSameMutex,NULL); 63 #endif 64 65 66 pthread_join(thread_1,NULL); 67 pthread_join(thread_2,NULL); 68 pthread_join(thread_3,NULL); 69 70 pthread_mutex_destroy(&mutex1); 71 pthread_cond_destroy(&cond); 72 return 0; 73 74 }
使用broadcast的运行结果:
使用signal的运行结果:
分析:
- 当使用broadcast方式时,两个被阻塞的线程都被唤醒了,被唤醒的线程想做的第一件事就是对mutex1加锁,在本次运行过程中thread_1加锁成功了,虽然thread_2没有成功抢到锁,但是它也没有闲着,它一直在尝试对mutex1进行加锁,皇天不负有心人,在thread_1执行完毕释放锁后,thread_2成功拿到了锁,然后顺利执行。
- 当使用signal方式时,thread_1和thread_2中只被唤醒了一个线程,在本次运行中是thread_1被唤醒了,而因为thread_2没有被唤醒,因此它一直被阻塞在pthread_cond_wait处,所以最终只有thread_1执行完毕。
第二种情况:多个线程等待同一个cond,并且分别不同的mutex加锁。
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <pthread.h> 4 #include <stdlib.h> 5 6 pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 7 pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; 8 pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; 9 10 void* thread_task1(void* arg) 11 { 12 pthread_mutex_lock(&mutex1); 13 14 pthread_cond_wait(&cond,&mutex1); 15 16 printf("thread_task1 start working\n"); 17 sleep(2); 18 printf("thread_task1 works over\n"); 19 pthread_mutex_unlock(&mutex1); 20 21 return NULL; 22 23 24 25 } 26 27 void* thread_task2(void* arg) 28 { 29 pthread_mutex_lock(&mutex2); 30 31 pthread_cond_wait(&cond,&mutex2); 32 33 printf("thread_task2 start working\n"); 34 sleep(2); 35 printf("thread_task2 works over\n"); 36 pthread_mutex_unlock(&mutex2); 37 38 return NULL; 39 40 41 } 42 43 void* broadcastDiffMutex(void* arg) 44 { 45 pthread_cond_broadcast(&cond); 46 return NULL; 47 48 } 49 50 void* signalDiffMutex(void* arg) 51 { 52 pthread_cond_signal(&cond); 53 return NULL; 54 55 } 56 57 int main() 58 { 59 pthread_t thread_1,thread_2,thread_3; 60 pthread_create(&thread_1,NULL,thread_task1,NULL); 61 pthread_create(&thread_2,NULL,thread_task2,NULL); 62 sleep(2); 63 64 #ifdef SIGNAL 65 pthread_create(&thread_3,NULL,signalDiffMutex,NULL); 66 #else 67 pthread_create(&thread_3,NULL,broadcastDiffMutex,NULL); 68 #endif 69 70 71 pthread_join(thread_1,NULL); 72 pthread_join(thread_2,NULL); 73 pthread_join(thread_3,NULL); 74 75 pthread_mutex_destroy(&mutex1); 76 pthread_mutex_destroy(&mutex2); 77 pthread_cond_destroy(&cond); 78 return 0; 79 80 }
使用broadcast的效果:
使用signal的效果
分析:
- 当使用broadcast方式时,因为两个线程都被唤醒了,且它们想要加的锁并没有竞争关系,因此它们是并发执行的,而不必像前一种情况中那样必须一前一后执行。
- 当使用signal方式时,只被唤醒了一个线程,因此只有一个线程成功执行。
标签:mutex1,thread,void,broadcast,cond,pthread,NULL 来源: https://www.cnblogs.com/XiaoXiaoShuai-/p/11855408.html