两个小朋友数数,从一数到100
C代码实现如下
#include<stdio.h>
#include<pthread.h>
int a=0;
void *my_fun1(void *arg)
{
int i=0;
for(i=0;i<50;i++)
{
int tmp=a;
tmp++;
usleep(10);
a=tmp;
printf("pthread 1 %d\n",a);
}
return NULL;
}
void *my_fun2(void *arg)
{
int i=0;
for(i=0;i<50;i++)
{
int tmp=a;
tmp++;
usleep(10);
a=tmp;
printf("pthread 2 %d\n",a);
}
return NULL;
}
int main(void)
{
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,my_fun1,NULL);
pthread_create(&tid2,NULL,my_fun2,NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
}
编译运行以后结果如下
这是为什么呢?
多线程的执行顺序是不线性的,没有规律可言
这是一个简单的运行时候数据的模拟图
全局变量是存在磁盘里面的,在程序运行的时候要从磁盘经过内存,三级,二级,一级缓存从到cpu里面,同样,cpu运算之后的结果也会送回磁盘,但是呢,我们在使用多线程的时候会出现cpu执行完还没有将结果送到磁盘的时候,另外一个线程就从磁盘读取数据了,从而出现数据不同步的情况,这时候就需要用到-----------------锁
在之前的程序上改动如下
红色的为加锁和解锁,蓝色区域为临界资源,也就是两个线程同时操作的那块资源,我们将他们用锁锁起来就不会出现数据不同步的情况了
就像一个人去上厕所,进去厕所之后要将厕所门锁起来,然后另外一个人进不来,当这个人上完了厕所,解开反锁,另一个人才能进去,这个例子里面,线程相当于人,临界资源相当于厕所。
还有一点改动就是在主函数里面,一开始我们要初始化锁 pthread_mutex_init(&mutex,NULL);
用完了所以后我们要销毁锁pthread_mutex_destroy(&mutex);