问题描述
程序多线程间共享变量出现取值不同步的问题,同一个变量取出来的数据不一致
问题分析
查看最近修改记录发现,修改了Makefile,增加了编译优化项-O2,由此分析是由于编译器优化导致
解决方案
将线程共享的变量增加volatile修饰即可,一个变量被volatile修饰之后
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改
了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序,即保证了操作的有序性。
例子验证
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int a = 1;
void *child_pth_fun(void *arg);
int main(){
int b, c;
volatile int val = 10000000;
//创建子线程
pthread_t child_pth_id;
pthread_create(&child_pth_id, NULL, child_pth_fun, NULL);
b = a;
//模拟一段很长的程序段,消耗主线程时间片,以便系统调度子线程
while(val--);
c = a;
if(c == b)
printf("In main pthread1: a=%d, b=%d, c=%d\n", a, b, a);
else
printf("In main pthread2: a=%d, b=%d, c=%d\n", a, b, a);
pthread_join(child_pth_id, NULL);
return 0;
}
void *child_pth_fun(void *arg){
//子线程修改共享的全局变量
a = 4;
printf("In child pthread: a=%d\n", a);
}
默认编译,结果显示正常
gcc aa.c -lpthread
# ./a.out
In child pthread: a=4
In main pthread2: a=4, b=1, c=4
增加编译优化,结果显示异常
gcc -O2 aa.c -lpthread
结果输出
# ./a.out
In child pthread: a=4
In main pthread1: a=1, b=1, c=1
发现a的值不同步,修改程序,将
int a=1;
修改为
volatile int a=1;
编译验证
gcc -O2 aa.c -lpthread
输出结果正常
# ./a.out
In child pthread: a=4
In main pthread2: a=4, b=1, c=4
至此,可以看出多线程数据不同步是由于编译优化导致,具体可以参考以下链接,博主分析很详细
参考链接: