操作系统_并发_1.2_共享数据
一、线程访问共享数据的相互作用
一个例子,两个线程希望更新全局共享变量。
编译和运行与上一节相同
#include<stdio.h>
#include<pthread.h>
//#include"mythreads.h"
static volatile int counter = 0;
void *mythread(void *arg){
printf("%s:begin\n",(char *)arg);
int i;
for(i=0;i<1e7;i++){
counter = counter + 1;
}
printf("%s:done\n",(char *)arg);
return NULL;
}
int main(int argc,char *argv[])
{
pthread_t p1,p2;
printf("main:begin (counter = %d)\n",counter);
pthread_create(&p1,NULL,mythread,"A");
pthread_create(&p2,NULL,mythread,"B");
pthread_join(p1,NULL);
pthread_join(p2,NULL);
printf("main: done with both (counter = %d)\n",counter);
return 0;
}
具体到每个线程,正在做的事情,都是调用mythread
函数,像共享变量计数器添加一个数字,并在循环中执行1000万(10^7)次,因此预期结果是:20000000。
但很遗憾,并不能获得预期的结果
尝试新的跨平台 PowerShell https://aka.ms/pscore6
PS E:\MyGit\operation-system_-learning> cd .\example\
PS E:\MyGit\operation-system_-learning\example> .\SharedData.c
PS E:\MyGit\operation-system_-learning\example> .\SharedData.exe
main:begin (counter = 0)
A:begin
B:begin
B:done
A:done
main: done with both (counter = 11040785)
PS E:\MyGit\operation-system_-learning\example> .\SharedData.exe
main:begin (counter = 0)
A:begin
B:begin
B:done
A:done
main: done with both (counter = 10658962)
PS E:\MyGit\operation-system_-learning\example> .\SharedData.exe
main:begin (counter = 0)
A:begin
B:begin
B:done
A:done
main: done with both (counter = 10605036)
PS E:\MyGit\operation-system_-learning\example>
可以看到,每次运行不但会产生错误,而且会得到不同的结果。
why?
我们具体来看一下,详见下节,不可控的调度。