多线程编程中的问题

现在计算机的发展,多核将成为一个趋势。

所以多线程编程也必然 将越来越流行。

不过,多线程编程同传统编程有很多不同。对计算机体系结构的不了解很可能会导致错误代码的产生。

比如说下面是一个多线程程序,线程1执行代码:
....

x=1;
y=1;
....

线程2执行代码

...
if(y==1){
    if(x==0){
         y=0;
   }
}
....
假设x,y都是全局变量,而且这两个线程中所有其他代码都没有对数据x,y进行访问,那么请问上面代码执行完后,
变量x,y的值是多少呢?
很显然,最终x,y的值很可能都是1。但是还有一种可能就是最终x=1,y=0.

导致这个结果的第一个可能原因是对于编译器来说,在分别优化两个线程的代码时,可能会交换没有数据依赖关系的代码的顺序,比如线程1的代码可能回被优化成:
y=1;

x=1;

这对于传统单线程的代码是没有任何问题的。同样线程2中对x和y读取的顺序也可能被交换。

那么如果我们不让编译器进行优化,比如使用O0选项进行编译,是不是上面的代码最终结果就不可能是x=1,y=0了呢?

答案还是否定的,这个是因为现代计算机都采用了缓存(cache)结构, 所有对内存的访问都会首先通过缓存进行,只有缓存空间不够时,才会对内存进行访问。

所以对于上面的代码,当线程1将x,y赋值为1时,有可能对x的写操作只是写在缓存上(另一个处理器看不到),而对y进行写操作时,可能由于缓存空间不够,直接写入内存,结果被另一个处理器读取到。

所以即使上面代码没有经过任何优化,(或者我们直接书写汇编代码,按上面顺序进行访问),其结果也是不确定的。

那么如果要在多线程程序中事先类似上面代码的功能,我们需要如何操作呢?

有两种方法:

i)总是使用操作系统提供的线程间通讯函数进行线程间同步和通讯。

ii)将x,y定义成volatile变量,比如
volatile int x;

这两种方法都会导致编译出来的代码性能很大的降低,所以我们在写多线程代码时要注意尽量减少线程之间通讯的代码。

 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值