Chinaunix

标题: UINT8/UINT32做为共享数据,是否需要加锁 - 原子操作问题 [打印本页]

作者: newroot_phy    时间: 2010-12-27 23:20
标题: UINT8/UINT32做为共享数据,是否需要加锁 - 原子操作问题
本帖最后由 newroot_phy 于 2010-12-29 13:58 编辑

读写一个8bit的char需要加锁吗?!在什么具体环境下,为什么!

前些天跟朋友讨论了这个问题,朋友说在汇编级别上,一个读操作也是有多条指令的,所以也是有可能被中断的!

以前我一直以为读写一个int, char之类的数据是不需要加锁的,我也是从外部(网络)了解到这个观点,没有什么理论依据,所以请大家指点!

-----------------
1. 修改主题
作者: xiaobenniao514    时间: 2010-12-28 09:23
不需要,系统api函数就是一原子操作,不会中间中断的
作者: madoldman    时间: 2010-12-28 09:29
不需要,系统api函数就是一原子操作,不会中间中断的
xiaobenniao514 发表于 2010-12-28 09:23

还真是什么都敢说
作者: 雨过白鹭洲    时间: 2010-12-28 09:33
有人说这些操作都不是原子的
作者: linyunxian    时间: 2010-12-28 09:38
读写一个8bit的char需要加锁吗?!在什么具体环境下,为什么!

前些天跟朋友讨论了这个问题,朋友说在汇编级别 ...
newroot_phy 发表于 2010-12-27 23:20



    弄清楚是否原子跟是否可重入,是否线程安全后,就不会迷惑了。 对于应用来说,最多只需要考虑到可重入的问题
作者: wwwhenan    时间: 2010-12-28 09:50
不一定要加锁,可以用原子变量嘛
作者: newroot_phy    时间: 2010-12-28 13:01
不需要,系统api函数就是一原子操作,不会中间中断的
xiaobenniao514 发表于 2010-12-28 09:23



    {:3_205:} 不是吧!这跟系统API有什么关系!?
作者: newroot_phy    时间: 2010-12-28 13:06
不一定要加锁,可以用原子变量嘛
wwwhenan 发表于 2010-12-28 09:50



    呵呵!!不局限某种特殊的数据类型!

我只明想找些证据证明存取uint8/uint32之类的数据类型是否是原子操作!
作者: amarant    时间: 2010-12-28 13:10
用了原子操作就不用吧,如果没用可能会产生读出/写入的汇编,就会被打断了。
作者: newroot_phy    时间: 2010-12-28 13:36
弄清楚是否原子跟是否可重入,是否线程安全后,就不会迷惑了。 对于应用来说,最多只需要考虑到可 ...
linyunxian 发表于 2010-12-28 09:38



可重入函数
    可重入的函数简单来说就是可以被中断的函数
原子操作
    在一个CPU时钟内保证完成的一个指令

不知道理解对不对!

刚刚跟同事又聊了一下,结论是读写Uint8是有可能被中断的,拿一个赋值操作(MIPS)来说a = b;(因为不熟悉汇编,没法通过汇编进行说明)

1. load b 地址到寄存器 R1
2. load b 的值到寄存器 R2
3. load a 地址到寄存器 R3
4. 将R2赋值到R3

所以目前的结论是UINT8在多线程(进程)之间共享(读写),是需要加锁保护的!

请大家补充!
作者: xiaobenniao514    时间: 2010-12-28 16:41
哦,我理解错了。我想表达的意思是,我看那个APUE里说,例如在文件结尾写东西,如果两个函数实现,先定位到最后,再写,就可能会中间有中断,如果只有一个函数实现,就不会出现此问题。
作者: wb112200    时间: 2010-12-28 17:10
32位的CPU 一个CPU时间处理32位 是不是程序占用的这8位 有可能恰好被分配到2个CPU时间 进而可能引发冲突? 所有需要加锁...   还是逻辑运算 需要多条指令完成 所有需要加锁?
作者: chenzhanyiczy    时间: 2010-12-28 19:40
读写一个8bit的char需要加锁吗?!
-->单cpu,根本不用。多cpu可能需要。无论如何,都要注意编译器的优化
作者: linyunxian    时间: 2010-12-28 20:49
可重入函数
    可重入的函数简单来说就是可以被中断的函数
原子操作
    在一个CPU时钟内保证完成 ...
newroot_phy 发表于 2010-12-28 13:36



    多线程有自己的栈。线程切换时入栈出栈,保存上下文是内核做的事,只要是线程安全就可以。如果是信号的话,只要可重入就行。不必要考虑到cpu的原子性(除非是对一个全局变量访问时)。
作者: newroot_phy    时间: 2010-12-28 23:21
多线程有自己的栈。线程切换时入栈出栈,保存上下文是内核做的事,只要是线程安全就可以。如果是 ...
linyunxian 发表于 2010-12-28 20:49



  
你事实上没有回答我的问题!

这个贴中你要求有两个
1. 如果是多线程: 只要线程安全就可以   <= 这就是我所问的,如何实现线程安全,当然是以某种方法实现线程间共享数据访问的同步,哪么Uint8之类的数据是否需要同步,这才是我的问题.

2. 信号:这个跟多线程对共享数据的访问没有什么本质的区别.

对于"除非是对一个全局变量访问时", 这个说话好像也不太合适, 不一定是全局变量的访问才有这个问题,我觉得用线程/进程间可访问的数据比较合适.
作者: newroot_phy    时间: 2010-12-28 23:25
读写一个8bit的char需要加锁吗?!
-->单cpu,根本不用。多cpu可能需要。无论如何,都要注意编译器的优化
chenzhanyiczy 发表于 2010-12-28 19:40



    为什么没有必要?!
    据我的理解,就算在单CPU上, 对UINT8的访问也是由多条汇编指令完成,这些指令的执行完全有可能被中断!

     不太明白你所说的"都要注意编译器的优化"是什么意思, 是对UINT8数据访问的多条指令进行加锁以实现原子操作吗?
作者: newroot_phy    时间: 2010-12-28 23:32
32位的CPU 一个CPU时间处理32位 是不是程序占用的这8位 有可能恰好被分配到2个CPU时间 进而可能引发冲突?  ...
wb112200 发表于 2010-12-28 17:10



    32位的CPU 一个CPU时间处理32位 是不是程序占用的这8位 有可能恰好被分配到2个CPU时间 进而可能引发冲突? 所有需要加锁...   还是逻辑运算 需要多条指令完成 所有需要加锁?

1. 32位说的是CPU一个时钟周期内所能处理的数据量, 跟这个应该没有关系吧! <=我不确定它们之间有什么关系.
2. 同意你的第二个观点. => "逻辑运算 需要多条指令完成"
作者: newroot_phy    时间: 2010-12-28 23:40
哦,我理解错了。我想表达的意思是,我看那个APUE里说,例如在文件结尾写东西,如果两个函数实现,先定位到 ...
xiaobenniao514 发表于 2010-12-28 16:41



兄弟,你把我说糊涂了,这跟几个函数实现没有什么关系吧!

或许我没明白你想表达的意思! 见笑!!
作者: mik    时间: 2010-12-28 23:50
这种问题光 c/c++ 版已经被讨论过很多次了。
LZ想一想到底想问什么
作者: newroot_phy    时间: 2010-12-29 12:59
本帖最后由 newroot_phy 于 2010-12-29 13:00 编辑
这种问题光 c/c++ 版已经被讨论过很多次了。
LZ想一想到底想问什么
mik 发表于 2010-12-28 23:50



我想问的是, 对共享基本数据类型(char, int ...)的读写,在各种情况下(多线程/多进程/多核)(X86/MIPS/SPARC),是否有可能被中断!为什么?!

是否有相关的资料证实这一点!?




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2