1 创建一个线程
这段代码中的
pthread_create(&tid,NULL,thr_fun,"1");
这一行将会创建一个线程,并且thr_fun方法将会在此线程中执行。“1”代表方法中的参数。
2 编译目标程序
变异后,将会得到二进制的可执行程序
执行后 发现只打印了main thread 说明子线程乜有执行。这是因为主线程退出了,所有的子线程就终止了。所以没有打印。
主线程休眠一秒后
再次执行后
3 pthread-join 阻塞线程
等之前的代码执行结束后,再往下执行
这段代码中的
pthread_join(tid,&rval);
意思是在线程tid执行后,在向下执行。其中的&rval表示线程返回的参数。
执行后
可以看到结尾出现了一个错误。
添加了这一行后
pthread_exit(2);
再次执行
可以看出线程退出传的参数赋值给了rval。
4 线程互斥
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <pthread.h>
5
6 int i = 0;
7
8 void* thr_fun(void* arg){
9 char* no = (char*)arg;
10
11 for(;i<5;i++){
12 printf("%s thread, i:%d\n",no,i);
13 sleep(1);
14 }
15 i=0;
16 }
17
18
19 void main(){
20 pthread_t tid1,tid2;
21 pthread_create(&tid1,NULL,thr_fun,"No1");
22
23 pthread_create(&tid2,NULL,thr_fun,"No2");
24
25 pthread_join(tid1,NULL);
26
27 pthread_join(tid2,NULL);
28
29 }
这段代码意思是同时创建连个线程并在线程中操作同一个变量i。
执行后
root@iZ2zea2ti45wm5djtomfm5Z:/usr/yeliang/pthread# ./02
No2 thread, i:0
No1 thread, i:0
No2 thread, i:1
No1 thread, i:2
No2 thread, i:3
No1 thread, i:4
No1 thread, i:1
No1 thread, i:2
No1 thread, i:3
No1 thread, i:4
可以看出线程1先打印0,然后直接打印2。说明两个线程同时操作i.
现在想让线程1和2互不影响
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <pthread.h>
5
6 int i = 0;
7
8 //互斥锁
9 pthread_mutex_t mutex;
10
11 void* thr_fun(void* arg){
12 //加锁
13 pthread_mutex_lock(&mutex);
14 char* no = (char*)arg;
15
16 for(;i<5;i++){
17 printf("%s thread, i:%d\n",no,i);
18 sleep(1);
19 }
20 i=0;
21 //解锁
22 pthread_mutex_unlock(&mutex);
23 }
24
25
26 void main(){
27 pthread_t tid1,tid2;
28 //初始化互斥锁
29 pthread_mutex_init(&mutex,NULL);
30 pthread_create(&tid1,NULL,thr_fun,"No1");
31
32 pthread_create(&tid2,NULL,thr_fun,"No2");
33
34 pthread_join(tid1,NULL);
35
36 pthread_join(tid2,NULL);
37
38 //销毁互斥
39 pthread_mutex_destory(&mutex);
40 }
这段代码中的pthread_mutex_t mutex;
表示互斥锁。
加锁 pthread_mutex_lock(&mutex);
解锁 pthread_mutex_unlock(&mutex);
也就是说当一个线程在执行加锁部分的内容时,其他线程不能访问。
执行后,打印结果
root@iZ2zea2ti45wm5djtomfm5Z:/usr/yeliang/pthread# ./02
No2 thread, i:0
No2 thread, i:1
No2 thread, i:2
No2 thread, i:3
No2 thread, i:4
No1 thread, i:0
No1 thread, i:1
No1 thread, i:2
No1 thread, i:3
No1 thread, i:4
此时,线程1和2互不影响。
5 生产者模式
开启两个线程,一个不断的生产另一个不断的消费。
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <pthread.h>
5
6 //消费者数量
7 #define CONSUMER_NUM 1
8
9 //生产者数量
10 #define PRODUCER_NUM 2
11
12 pthread_t pids[CONSUMER_NUM+PRODUCER_NUM];
13
14
15 //产品队列
16 int ready = 0;
17
18 //互斥锁
19 pthread_mutex_t mutex;
20
21 //条件变量
22 pthread_cond_t has_product;
23
24 //生产
25 void* producer(void* arg){
26 int no = (int)arg;
27 //条件变量
28 for(;;){
29 pthread_mutex_lock(&mutex);
30 //往队列中添加产品
31 ready++;
32 printf("producer %d,produce product\n",no);
33 fflush(NULL);
34 //通知消费者,有新的产品可以消费了
35 //会阻塞输出
36 pthread_cond_signal(&has_product);
37 printf("producer %d singnal\n",no);
38 pthread_mutex_unlock(&mutex);
39 sleep(1);
40 }
41
42 }
43
44 //消费者
45 void* consumer(void* arg){
46 int num = (int)arg;
47 for(;;){
48 pthread_mutex_lock(&mutex);
49 while(ready==0){
50 //没有产品继续等待
51 //1 阻塞等待has_prodeuct被唤醒
52 //2 释放互斥锁 pthread_mutex_unlock
53 //3 被唤醒时 解除阻塞 重新申请获得互斥锁 pthread_mutex_lock
54 pthread_cond_wait(&has_product,&mutex);
55 }
56 //有产品,消费产品
57 ready--;
58 printf("%dconsume product\n",num);
59
60 sleep(1);
61 pthread_mutex_unlock(&mutex);
62 }
63 }
64
65
66 void main(){
67
68 //初始化互斥锁和条件变量
69 pthread_mutex_init(&mutex,NULL);
70 pthread_cond_init(&has_product,NULL);
71
72 int i;
73 for(i=0;i<PRODUCER_NUM;i++){
74 //生产者线程
75 pthread_create(&pids[i],NULL,producer,(void*)i);
76 }
77
78 for(i=0;i<CONSUMER_NUM;i++){
79 //消费者线程
80 pthread_create(&pids[PRODUCER_NUM+i],NULL,consumer,(void*)i);
81 }
82
83 //等待
84 for(i=0;i<CONSUMER_NUM+PRODUCER_NUM;i++){
85 pthread_join(pids[i],NULL);
86 }
87
88 //销毁互斥锁和条件变量
89
90
91 pthread_mutex_destroy(&mutex);
92 pthread_cond_destroy(&has_product);
93 }
打印结果
tabstop=8root@iZ2zea2ti45wm5djtomfm5Z:/usr/yeliang/pthread# ./03
producer 1,produce product
producer 1 singnal
0consume product
producer 1,produce product
producer 1 singnal
0consume product
producer 1,produce product
producer 1 singnal
0consume product