鱼C论坛

 找回密码
 立即注册
查看: 4121|回复: 11

[技术交流] 悬赏讨论 “由i++引起bug!!!”

[复制链接]
发表于 2012-9-7 22:28:43 | 显示全部楼层 |阅读模式
20鱼币
i++;这句自增代码代码想必大家都很熟悉了,但是这句代码在16位的编译器中可能会引起bug哦:o,
提示:多线程程序。
第一个解释清楚的同学有奖哦~~~希望大家积极参与讨论哈。。。:lol

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-9-7 23:05:48 | 显示全部楼层
先看看我的鱼B有多少
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-9-7 23:07:05 | 显示全部楼层
这不是我能来的地方 以后再说吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-9-7 23:21:27 | 显示全部楼层
i++写成汇编, 假设操作的寄存器是eax
mov eax,i
add eax,1
mov i,eax
第一条 将i的值从内存中读取到寄存器eax中。

第二条 将寄存器eax中的值与1相加,计算结果仍存入寄存器eax中。

第三条 将寄存器eax中的值写回内存中。

       这样由于线程执行的并发性,很可能线程1执行到第二句时,线程2开始执行,线程2将原来的值又写入寄存器eax中,这样线程1所主要计算的值就被线程2修改了。

这样的结果就不可预知了

要解决可以用
InterlockedIncrement
这个api
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-9-8 00:08:54 | 显示全部楼层

你说的有些道理,不过当线程1挂起时,它的线程环境会被系统保存的,
当再次wake up 的时候,寄存器的内容会恢复的,所以不会出现你说的这种情况。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-9-8 00:16:58 | 显示全部楼层
我上面说了是在16位的程序可能会出现bug,再提示下:关于多线程共享变量的~~
大家继续讨论哈。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-9-8 02:02:08 | 显示全部楼层
关注一下。期待正确答案的到来。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-9-8 08:47:53 | 显示全部楼层
我的都是32位的 没试过16位的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-9-8 21:37:49 | 显示全部楼层
哎,我觉得在未来几年32位的操作系统都不会存在的,社会发展很快的,没别的意思,就是有感而发
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-9-8 23:26:32 | 显示全部楼层
bui159说的基本是对的,主要就是由于i++不是原子操作。
假设有变量int i=0;
有线程A和B要进行i++操作
假设执行流程如下:
1.线程A先执行i++,A将i的值读入寄存器,将寄存器的值加1。此时线程A中止执行,i的值还是0。
2.线程B连续不间断执行100次i++,此时i的值是100;
3.线程A恢复执行,将寄存器里的1写入i

综上,线程A和线程B总共进行了101次i++操作,但i最终的值是1.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-9-9 19:46:45 | 显示全部楼层
ding yi xi 与比一个
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-9-13 13:04:06 | 显示全部楼层
刚学到自增自减,多线程不懂。恩恩,不懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 15:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表