pthread_cond_broadcast & pthread_cond_signal


pthread_cond_broadcast(&cond1)的作用是喚醒所有正在pthread_cond_wait(&cond1,&mutex1)的線程。

pthread_cond_signal(&cond1)的的作用是喚醒所有正在pthread_cond_wait(&cond1,&mutex1)的至少一個線程。(雖然我還沒碰到過多於一個線程的情況,但是man幫組手冊上說的是至少一個)

 

下面分為情況討論一下這兩個函數的效果。

第一種情況:多個線程等待同一個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     return 0;
76 
77 }

 

 

 

 

使用broadcast的運行結果:

 

 

 使用signal的運行結果:

分析:

  1. 當使用broadcast方式時,兩個被阻塞的線程都被喚醒了,被喚醒的線程將變為pthread_mutex_lock(mutex1)的狀態,他們將搶着對mutex1加鎖,在本次運行過程中thread_1加鎖成功了,thread_2沒有成功搶到鎖,於是它就被阻塞了,在thread_1執行完畢釋放鎖后,會通知所有被阻塞在mutex1上的線程,於是thread_2最終成功拿到了鎖,然后順利執行。
  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     return 0;
76 
77 }

 

 

 

 

使用broadcast的效果:

 

使用signal的效果

 

 分析:

  1. 當使用broadcast方式時,因為兩個線程都被喚醒了,且它們想要加的鎖並沒有競爭關系,因此它們是並發執行的,而不必像前一種情況中那樣必須一前一后執行。
  2. 當使用signal方式時,只被喚醒了一個線程,因此只有一個線程成功執行。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM