首页 > 试题广场 >

有一个变量int a=0;两个线程同时进行+1操作,每个线程

[单选题]
有一个变量int a=0;两个线程同时进行+1操作,每个线程加100次,不加锁,最后a的值是()?
  • 200
  • <=200
  • >=200
  • 都有可能
推荐
答案是选 B

i++在两个线程里边分别执行100次,能得到的最大值和最小值分别是多少?

i++只需要执行一条指令,并不能保证多个线程i++,操作同一个i,可以得到正确的结果。因为还有寄存器的因素,多个cpu对应多个寄存器。每次要先把i从内存复制到寄存器,然后++,然后再把i复制到内存中,这需要至少3步。从这个意义上讲,说i++是原子的并不对。

 

如此,假设两个线程的执行步骤如下: 

 1. 线程A执行第一次i++,取出内存中的i,值为0,存放到寄存器后执行加1,此时CPU1的寄存器中值为1,内存中为0;

 2. 线程B执行第一次i++,取出内存中的i,值为0,存放到寄存器后执行加1,此时CPU2的寄存器中值为1,内存中为0;

 3. 线程A继续执行完成第99次i++,并把值放回内存,此时CPU1中寄存器的值为99,内存中为99;

 4. 线程B继续执行第一次i++,将其值放回内存,此时CPU2中的寄存器值为1,内存中为1;

 5. 线程A执行第100次i++,将内存中的值取回CPU1的寄存器,并执行加1,此时CPU1的寄存器中的值为2,内存中为1;

 6. 线程B执行完所有操作,并将其放回内存,此时CPU2的寄存器值为100,内存中为100; 

 7. 线程A执行100次操作的最后一部分,将CPU1中的寄存器值放回内存,内存中值为2;

 8. 结束!

所以该题目便可以得出最终结果,最小值为2,最大值为200。

编辑于 2015-01-27 15:01:16 回复(3)
多核cpu,最小值2,最大值200,参http://zhan.renren.com/h5/entry/3602888498047361672
单核cpu,最小值100,最大值200
发表于 2015-03-05 10:37:26 回复(0)
答案:B
最小值100  最大值200
两个线程分别记为线程1和线程2,i++相当于取出i的值,加1,再放回去
第一种极端情况:每次线程一取出i的值后CPU时间切换到线程二,线程二也取出i的值,取到的值和线程一相等,线程二给i加一后放回去,线程一也将i加一后放回去,放回去的值也相等,相当于两个线程都执行一次i++操作,i的值只增加1,这样操作100次i的值为100
第二种极端情况:线程一和线程二间隔操作,即线程一对i++操作完成,把已经加一的数据放回去之后线程二再操作,轮流进行,最后每个线程都对i加了100次,i的值为200
发表于 2015-01-29 17:28:10 回复(0)
B
解释:
++这个操作不是原子操作,在汇编中加1有三步:
1.先mov读取
2.再add加操作
3.最后ldr写入
由于线程是同步的,所以,如果他们同时进行mov操作,值就不会变。
如int i=5;同时mov的5再加1=6;在同时ldr写入,好像进行了两次加法,但值还是6.
所以在这里两个线程++100次,值最大的情况就是每次++都不重叠,最大值是200,考虑重叠的情况,小于200的值都是有可能的.
补充:
线程互斥锁的作用就在这里:保证两个i变量同时能被一个线程使用,也就是mov时只能有一个进行读取。

发表于 2015-01-27 13:51:03 回复(0)
分单核核多核情况,以下是我的理解,有错误的话请指正:
i++分三步,从内存读入寄存器,计算,寄存器结果写入内存。
多核情况:
cpu2把0从内存读入到寄存器,cpu1执行了99次运算,写入内存,cpu2执行一次写入内存,内存为1,然后cpu1再读入寄存器,为1,然后cpu2执行结束,cpu1再执行最后一次加1并写入内存,结果为2。这样情况会导致结果为2-200。
单核情况:
两个线程共用相同寄存器,第一个线程执行cpu读入寄存器,加1,还没写入内存,第二个线程读入寄存器,会覆盖寄存器的值,如果线程2继续执行会写入内存为2,第一个线程写入也是2(第一个线程的寄存器值变化为1,2,1,2),此时会导致两个线程加1,只加一次。这样情况会导致结果为100-200。

编辑于 2023-11-11 23:26:47 回复(0)
B
发表于 2020-04-04 12:13:46 回复(0)
题里有说是i++吗,这帮人拿着同一个答案装自己的东西一顿bb,要是人家的+1是a=a+1呢?
发表于 2017-12-13 19:07:47 回复(0)
多核cpu,最小值2,最大值200,参http://zhan.renren.com/h5/entry/3602888498047361672
单核cpu,最小值100,最大值200
发表于 2017-04-14 09:56:24 回复(1)
该题目便可以得出最终结果,最小值为2,最大值为200。
发表于 2016-09-15 21:49:06 回复(0)
要注意,最大值为200,不可能比200还大。
发表于 2016-07-07 21:36:15 回复(0)
考虑单CPU的情况。
假设进程A取出了i的值,然后B突然抢到CPU,执行0+1并写回,而A又抢回CPU,此时他还在0+1=1写回。注意到两个进程各自执行了一次++操作,但是值依然是1喔~
如果按理想情况,就是200了,不然随时小于200是可能的,大于200就没有可能了吧。
发表于 2015-11-10 21:20:24 回复(0)
D

两个线程都要把某个全局变量增加1,这个操作在某平台需要三条指令完成:
1.从内存读变量值到寄存器
2.寄存器的值加1
3.将寄存器的值写回内存
对于多线程的程序,访问冲突的问题是很普遍的,这回导致结果的不可预知性。


发表于 2015-01-12 23:19:56 回复(0)