linux线程6(CSDN论坛上很火的一个讨论贴)

有一个全局变量

int sum=0

运行两个线程,代码如下:

for(int i=1;i<=50;i++)
   sum=sum+1;


问两个线程都运行完后,sum的取值范围。

本人虽然运行了n遍,结果都是100,但这是个概率事件,只是100的概率很大。为什么还可能出现其他结果?

这是由于线程执行的并发性,第一个线程还没执行完,就被另一个线程打断,即使只有一句,如果不是原子操作,仍然可以被打断。

博客中讨论出了多种结果,一些明显不对外,本人列出一些有说服力的结果,旨在理解多线程并发运行机制。

第一种:50-100

这种结果,考虑了线程之间相互覆盖的结果,最差也就相当于只跑一次但线程的效果,所以最低是50.

第二种:1-100

没有给出理由,但是1有没有可能出现呢?

第三种:2-100

本人比较认同这种结果,2-49之间的值几乎不可能,但是理论上存在,前面也说了,这是概率事件,只是出现的概率极低,下面分析2-49出现的可能。

首先让第一个线程取得sum=0,不执行加1操作;然后让第二个线程循环49次,接着用第一个线程运行到1-50之间的值,然后第二个线程取得这个值,接着第一个线程运行完,第二个线程在这个值的基础上加1,于是可以得到2-51之间的值,这个需要6次配合,条件苛刻,概率极低。

下面重点说下为什么最低是2.

很简单,就考虑最差的情况,如果第一个线程取得sum=0,还没有加1就被另一个线程打断,不管怎样,最后一定会完成这个加1动作,同样,第二个线程也是。所以最低不能低于2.

其实归根到底,问题出现的原因是,sum=sum+1不是原子操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值