Re: 问个问题,有兴趣的朋友可以帮忙看看啦
Windows内核调试
问个问题,有兴趣的朋友可以帮忙看看啦
mxzy55560593
2011-06-20, 23:48 下午
对x86CPU的一个4字节变量赋值是不是原子操作?比如一个线程赋值0x12345678,另一个线程赋值0x87654321,会不会出现其他线程读取这个变量的值不是这两个值中的一个? 也就是需不需要加锁的问题
Re: 问个问题,有兴趣的朋友可以帮忙看看啦
格蠹老雷
2011-06-21, 13:50 下午
如果是整型变量,编译器编译成一条MOV指令,那么执行这个MOV指令时一定是“原子”方式的
Re: 问个问题,有兴趣的朋友可以帮忙看看啦
wrong
2011-06-22, 11:42 上午
这个问题是比较热门的问题。
一般的理解是不是的。
多处理器,多核情况下,多个线程可能读写同一个变量,要加锁。
该加volatile的,加 volatile。
该用InterLocked,就用InterLocked。
Re: 问个问题,有兴趣的朋友可以帮忙看看啦
johnl
2011-06-26, 13:03 下午
取决于地址是否 4byte aligned, aligned 的是atomic, 可以不加锁。
Re: 问个问题,有兴趣的朋友可以帮忙看看啦
格蠹老雷
2011-06-26, 16:37 下午
多谢补充,不过,今天的编译器都会自动把四字节的整型变量按DWORD对齐的,除非定义结构时特别用pragma声明
Re: 问个问题,有兴趣的朋友可以帮忙看看啦
wrong
2011-06-30, 09:48 上午
找到一个帖子,希望有帮助。
http://user.qzone.qq.com/31731705/blog/1309358011
在单CPU系统中,能够在单条指令中完成的操作都是"原子操作",因为中断只能发生于指令之间。
但是,在多CPU结构中就不同了,由于系统中有多个CPU在独立地运行,即使能在单条指令中完成的操作也有可能受到干扰。我们以decl (递减指令)为例,这是一个典型的"读-改-写"过程,涉及两次内存访问。设想在不同CPU运行的两个进程都在递减某个内存单元的数值2,可能发生的情况是:
1. CPU A从内存单元把当前数值2装载进它的寄存器中;
2. CPU B从内存单元把当前数值2装载进它的寄存器中。
3. CPU A在它的寄存器中将计数值递减为1;
4. CPU B在它的寄存器中将计数值递减为1;
5. CPU A把修改后的计数值1写回内存单元。
6. CPU B把修改后的计数值1写回内存单元。
我们看到,内存里的计数值应该是0,然而它却是1。
可见原子操作不可能由软件单独保证--必须需要硬件的支持,因此是和架构相关的。在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性---这正是Interlocked 系互锁函数的本质和真象。
Re: 问个问题,有兴趣的朋友可以帮忙看看啦
skyworth
2011-06-30, 13:15 下午
呵呵,这个跟你说的东西是两个问题。
一个是操作中途被打断,另一个是操作被覆盖。