C编程下的并发方式互斥锁和条件变量,以前一直懵懂,通过这个示例代码才真正来了解如何配合使用互斥锁和条件变量。

互斥锁(mutex)和条件变量(cond)

pthread线程创建、互斥锁和条件变量的函数如下图

更多线程间通信,请点击上篇文章

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>

#define NUM_OF_TASKS 3
#define MAX_TASK_QUEUE 11

char tasklist[MAX_TASK_QUEUE]="ABCDEFGHIJ";
int head = 0;
int tail = 0;

int quit = 0;

pthread_mutex_t g_task_lock;
pthread_cond_t g_task_cv;

void *coder(void *notused){
pthread_t tid = pthread_self();

while(!quit){
pthread_mutex_lock(&g_task_lock);

while(tail == head){
if(quit){
pthread_mutex_unlock(&g_task_lock);
pthread_exit((void *)0);
}
printf("no task now! thread %u is waiting! \n", (unsigned int)tid);
pthread_cond_wait(&g_task_cv, &g_task_lock);
printf("have task now! thread %u is grabing thw task !\n", (unsigned int)tid);
}
char task = tasklist[head++];
pthread_mutex_unlock(&g_task_lock);
printf("thread %u has a task %c now! \n", (unsigned int)tid, task);
sleep(5);
printf("thread %u finish the task %c ! \n", (unsigned int)tid, task);
}
pthread_exit((void *)0);
}

int main(int argc, char *argv[]){
pthread_t threads[NUM_OF_TASKS];

int rc;
int t;

pthread_mutex_init(&g_task_lock,NULL);
pthread_cond_init(&g_task_cv,NULL);

for(t =0 ; t < NUM_OF_TASKS; t++){
rc = pthread_create(&threads[t], NULL, coder, NULL);
if(rc){
printf("ERROR , return from pthread_create %d \n" , rc);
exit(-1);
}
}

sleep(10);

for (t =1 ; t <= 4 ; t++){
pthread_mutex_lock(&g_task_lock);
tail += t;
printf("I am Boss , I assigned %d tasks, I notify all coder! \n", t);
pthread_cond_broadcast(&g_task_cv);
pthread_mutex_unlock(&g_task_lock);
// sleep用途:主线程等待其他线程完成的缓冲期,也可以取消不过得加上下面的while循环,不然任务未完成线程就退出了
sleep(20);
}
/*
for(t = 0 ; t < NUM_OF_TASKS; t++){
pthread_join(threads[t], NULL);
printf("pthread waiting %d finish! ",t);
}
*/
// 主线程等待其他线程完成任务
while(head != tail ){
// waiting finish tasks
}

pthread_mutex_lock(&g_task_lock);
quit = 1;
pthread_cond_broadcast(&g_task_cv);
pthread_mutex_unlock(&g_task_lock);

pthread_mutex_destroy(&g_task_lock);
pthread_cond_destroy(&g_task_cv);
pthread_exit(NULL);

}

编译代码gcc mutex-cond.c -o mutex-cond -lpthread

其示例整个运行过程如图:

以下是运行输出内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
[root@vm]/data/c# ./mutex-cond
no task now! thread 403633920 is waiting!
no task now! thread 395241216 is waiting!
no task now! thread 412026624 is waiting!
I am Boss , I assigned 1 tasks, I notify all coder!
have task now! thread 403633920 is grabing thw task !
thread 403633920 has a task A now!
have task now! thread 395241216 is grabing thw task !
no task now! thread 395241216 is waiting!
have task now! thread 412026624 is grabing thw task !
no task now! thread 412026624 is waiting!
thread 403633920 finish the task A !
no task now! thread 403633920 is waiting!
I am Boss , I assigned 2 tasks, I notify all coder!
have task now! thread 395241216 is grabing thw task !
thread 395241216 has a task B now!
have task now! thread 412026624 is grabing thw task !
thread 412026624 has a task C now!
have task now! thread 403633920 is grabing thw task !
no task now! thread 403633920 is waiting!
thread 395241216 finish the task B !
no task now! thread 395241216 is waiting!
thread 412026624 finish the task C !
no task now! thread 412026624 is waiting!
I am Boss , I assigned 3 tasks, I notify all coder!
have task now! thread 403633920 is grabing thw task !
thread 403633920 has a task D now!
have task now! thread 395241216 is grabing thw task !
thread 395241216 has a task E now!
have task now! thread 412026624 is grabing thw task !
thread 412026624 has a task F now!
thread 403633920 finish the task D !
no task now! thread 403633920 is waiting!
thread 395241216 finish the task E !
no task now! thread 395241216 is waiting!
thread 412026624 finish the task F !
no task now! thread 412026624 is waiting!
I am Boss , I assigned 4 tasks, I notify all coder!
have task now! thread 403633920 is grabing thw task !
thread 403633920 has a task G now!
have task now! thread 395241216 is grabing thw task !
thread 395241216 has a task H now!
have task now! thread 412026624 is grabing thw task !
thread 412026624 has a task I now!
thread 403633920 finish the task G !
thread 403633920 has a task J now!
thread 395241216 finish the task H !
no task now! thread 395241216 is waiting!
thread 412026624 finish the task I !
no task now! thread 412026624 is waiting!
thread 403633920 finish the task J !
no task now! thread 403633920 is waiting!
have task now! thread 395241216 is grabing thw task !
have task now! thread 412026624 is grabing thw task !
have task now! thread 403633920 is grabing thw task !