免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: mingjwan
打印 上一主题 下一主题

对int变量的赋值是原子操作吗? [复制链接]

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
131 [报告]
发表于 2006-08-11 16:48 |只看该作者
原帖由 mik 于 2006-8-11 16:46 发表



请问:这个lock()怎么实现呢?


多进程是信号量实现的。

论坛徽章:
0
132 [报告]
发表于 2006-08-11 16:50 |只看该作者
原帖由 mq110 于 2006-8-11 16:47 发表



是这样吗???

嗯,这个我是看了才说的

[ 本帖最后由 isjfk 于 2006-8-11 16:51 编辑 ]

论坛徽章:
0
133 [报告]
发表于 2006-08-11 16:51 |只看该作者
原帖由 mq110 于 2006-8-11 16:48 发表


多进程是信号量实现的。


这就与LZ所讨论的问题离题千里

论坛徽章:
0
134 [报告]
发表于 2006-08-11 16:55 |只看该作者
原帖由 mq110 于 2006-8-11 16:48 发表


多进程是信号量实现的。

信号量怎么实现的?信号量不是一个变量吗?

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
135 [报告]
发表于 2006-08-11 17:07 |只看该作者
原帖由 mik 于 2006-8-11 16:51 发表


这就与LZ所讨论的问题离题千里


呵呵,确实不是楼主讨论的情况。。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
136 [报告]
发表于 2006-08-11 17:15 |只看该作者
原帖由 isjfk 于 2006-8-11 16:50 发表

嗯,这个我是看了才说的



难道这不是volatile 起的作用???

论坛徽章:
0
137 [报告]
发表于 2006-08-11 17:16 |只看该作者
请问,到底什么是原子的?
以系统调用为例,哪个系统调用可以说是原子的?

以write(fd=STDERR_FILENO, buff, len=4)为例,
假设write需要2个mov就可以完成(多么有效率的系统啊)
mov1
...被打断,另一线程执行fd=STDOUT_FILENO,或者len = 8(实际情况要复杂得多,大家都明白)
mov2

这和i=j;有区别吗?

论坛徽章:
0
138 [报告]
发表于 2006-08-11 20:51 |只看该作者
原帖由 assiss 于 2006-8-11 17:16 发表
请问,到底什么是原子的?
以系统调用为例,哪个系统调用可以说是原子的?

以write(fd=STDERR_FILENO, buff, len=4)为例,
假设write需要2个mov就可以完成(多么有效率的系统啊)
mov1
...被打断,另一线程 ...

他们讨论的是机器底层的原子操作. 及一条或多条指令操作, 从开始到结束, 内存变量保持完整一致. 不受中断和别的CPU竞争的影响. 从外部看, 内存变量要么没变, 要么变成原子操作的结果, 其间不可能有第三种可能.

你说的系统调用read/write的原子性, 是狭义的逻辑的原子操作. 及对所有的应用程序, 看到的, 或能改变的(别的read/write请求), 要么是write前的内容, 要么是write后的内容, 不可能在中间. 当然kernel是可以看到,甚至更改中间结果的.

个人理解.

论坛徽章:
0
139 [报告]
发表于 2006-08-11 22:03 |只看该作者
gvim 引用的一段话很好地说明了原子操作的特征:

the set of operations either succeeds or fails all at once. No in-between state is accessible.

然而这两句话可以对赋值操作的原子性产生两种不同的理解(前面已经说过了):一种是赋值操作如果是由多条指令组成的话,由于没有同步保证,可以被中断,所以赋值过程不是原子的。另一种是从赋值的结果(是否存在中间状态)上来考虑。一些争论就是因为持有不同的理解造成的。我们更加关心的是结果,而不是过程,所以赋值的原子性一般指的是后一种情况。

考察一个操作的原子性就是考察此操作结果是否会由于中断而出现一个中间状态(in-between state)。

对于赋值来说,如果它是一个原子操作,则说明要么赋值已经成功,要么尚未进行,不存在只进行了一半的所谓中间状态的情况;如果出现了中间状态,则说明赋值不是一个原子操作。

这是从结果(状态)上来说的。至于由一条或者多条指令组成赋值过程是否是原子过程并不重要,关键是看其中的向赋值操作的左操作数中的写操作是由一条还是几条指令组成的:如果这样的写指令只有一条,则赋值是原子性的;如果多于一条写指令,则在第一次写操作后如果被中断的话其赋值结果就出现了一个中间状态,因此就不是原子操作。

修改:加上颜色强调一下。

[ 本帖最后由 whyglinux 于 2006-8-12 01:14 编辑 ]

论坛徽章:
0
140 [报告]
发表于 2006-08-11 22:20 |只看该作者
无论从理论层面上来说,还是操作层面上来说,赋值语句都未必是原子的(个别实现可能是),从理论上前面几位已经说的很清楚了,我想说说应用层面上,不加锁的多线程赋值产生的效果

各位可以随便翻一下经典的多线程编程的书籍,几乎每本都在访问共享变量的时候先加锁,再读写,如果赋值操作在操作层面上来说是原子的(先不管这个定义是不是准确,为了说明问题),那这些书都是多此一举的吗?因为按照前面几位的观点,即使赋值过程中被打断,也会由硬件或操作系统来做入/出栈的工作,从而保证赋值在操作层面上是原子的。

事实上不是,如果你曾经写过稍微复杂一点的多线程程序的,就会知道,不加锁的读写共享变量就会导致未知错误,程序或某个进/线程会在不可预知的地点毫无提示的退出,这就是我的经验,坐个马扎等着被拍砖
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP