线程同步的概念:
线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。
同时其它线程为保证数据一致性,不能调用该功能。
线程同步的例子:
创建两个线程,让两个线程共享一个全局变量int number,然后让每个线程数5000次数,看最后打印出这个number值是多少?
1 //线程同步
2 #include <pthread.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5
6 //定义宏
7 #define CNT 20000
8
9 //定义全局函数
10 int number = 0;
11
12
13 //线程执行函数1
14 void * mythread1 (void * arg)
15 {
16 printf("child thread,id == [%d], pid = [%d]\n",pthread_self(), getpid());
17
18 int i = 0;
19 int n ;
20 for(i; i < CNT; i++)
21 {
22 n = number;
23 n++;
24 number = n;
25 printf("1: [%d]\n",number);
26 }
27
28 }
29
30 //线程执行函数2
31 void * mythread2 (void * arg)
32 {
33 printf("child thread,id == [%d], pid = [%d]\n",pthread_self(), getpid());
34
35 int i = 0;
36 int n ;
37 for(i; i < CNT; i++)
38 {
39 n = number;
40 n++;
41 number = n;
42 printf("2: [%d]\n",number);
43 }
44 }
45
46 int main ()
47 {
48 //定义线程属性的变量
49 pthread_attr_t attr;
50
51 //初始化定义过的线程属性
52 pthread_attr_init(&attr);
53
54 //设置attr为分离属性
55 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
56
57
58 //创建子线程1
59 pthread_t thread1;
60 int ret = pthread_create(&thread1, &attr, mythread1, NULL);
61 if(ret != 0)
62 {
63 printf("pthread_create error,[%s]\n",strerror(ret));
64 return -1;
65 }
66
67 //创建子线程2
68 pthread_t thread2;
69 ret = pthread_create(&thread2, &attr, mythread2, NULL);
70 if(ret != 0)
71 {
72 printf("pthread_create error,[%s]\n",strerror(ret));
73 return -1;
74 }
75
76 printf("main thread,id == [%d], pid = [%d]\n",pthread_self(), getpid());
77
78
79 //释放线程属性
80 pthread_attr_destroy(&attr);
81
82 sleep(1); //让子线程有时间去运行
83
84 printf("number = %d\n",number);
85
86 printf("主线程结束\n");
87 return 0
88 }
通过上面的代码得出的结果可能有时候不是唯一的40000,有时候得到的数小于40000这个数字;
1. 上面的图片假设我们的全局变量number的值已经运行到了100这个数字;
2. 此时我们的线程1开始接着运行,n = number,此时 n= 100, number = 100,然后接
3. 着运行n++,那么n = 101了;
4. 就在这时,时间片轮到进程2了,进程2开始运行n = number,此时 n= 100, number=
5. 100,接着n++后n = 101了,再接着运行number= n,此时运行完进程2得到的number
6. 已经是101了,然后进程1又开始接着之前的运行,将number=n,又一遍将number的101
7. 的值覆盖一遍,number值还是101;
8. 所以通过上面的分析,运行两遍进程,但是数值number的值还只是加一次;
数据混乱的原因:
资源共享(独享资源则不会);
调度随机(线程操作共享资源的先后顺序不确定)
线程间缺乏必要的同步机制。
以上3点中,前两点不能改变,欲提高效率,传递数据,资源必须共享。只要其享资源,就一定会出现竞争。只要存在竞争关系,数据就很容易出现混乱。所以只能从第三点着手解决。使多个线程在访问共享资源的时候,出现互斥。
`