为什么原子操作能称为原子操作?
时间:2010-04-11
来源:互联网
static inline int atomic_dec_and_test(atomic_t *v)
{
unsigned char c;
asm volatile(LOCK_PREFIX "decl %0; sete %1"
: "+m" (v->counter), "=qm" (c)
: : "memory");
return c != 0;
}
这里面的汇编代码有两句,那么在执行第一句的时候发生了中断,那么岂非就是不原子操作了?
{
unsigned char c;
asm volatile(LOCK_PREFIX "decl %0; sete %1"
: "+m" (v->counter), "=qm" (c)
: : "memory");
return c != 0;
}
这里面的汇编代码有两句,那么在执行第一句的时候发生了中断,那么岂非就是不原子操作了?
作者: etoux 发布时间: 2010-04-11
本帖最后由 smalloc 于 2010-04-11 13:52 编辑
http://linux.chinaunix.net/bbs/v ... p;extra=&page=3
这么说来原子变量仅仅只保证第一个指令(即内存变量中的值减1)的原子性,这样不会产生计数和操作次数间的误差。
但是不保证计数和返回结果的一致性。
比如在多处理器,或者多任务,或者一个中断内与一个中断外,这些情况下对同一个原子变量的操作,其结果并不能保证一致性。
http://linux.chinaunix.net/bbs/v ... p;extra=&page=3
这么说来原子变量仅仅只保证第一个指令(即内存变量中的值减1)的原子性,这样不会产生计数和操作次数间的误差。
但是不保证计数和返回结果的一致性。
比如在多处理器,或者多任务,或者一个中断内与一个中断外,这些情况下对同一个原子变量的操作,其结果并不能保证一致性。
作者: smalloc 发布时间: 2010-04-11
回复 smalloc
我想问一问,这个LOCK锁住总线是怎么样的体现,能为我讲讲吗?
我想问一问,这个LOCK锁住总线是怎么样的体现,能为我讲讲吗?
作者: etoux 发布时间: 2010-08-21
(仔细看了看这段话仿佛明白了)
现在解释如下,首先说一点,任何一条汇编指令都是在一个不可分割的指令周期内完成的,也就是说,只有在指令周期内的最后一个点才回查询是否有中断发生了。现在说说lock_prefix的作用,首先想一想,因为任何的操作都在cpu的内部进行完成,所以如果想对变量v进行操作的话,那么在一个inc指令周期内,实际上cpu还是需要从内存总读出v的数值,然后对v处理之后,再写回到内存中去.这里需要注意的一个问题就是inc指令周期中,实际上发生了多次的对内存的进行访问,而这些对内存进行的访问实际上在地址总线上并不是原子操作的,也就是说.如果存在多个cpu的话,那么另外的cpu完全可以在该inc读出v的数值之后,另外的cpu这个时候就可以占用地址总线,从中读出v的数值,而这个时候,当前的cpu当修改v的数值之后,再回写到内存中,这个时候实际上就已经导致了内存的不一致的问题.因为另外的cpu的数值和真实的数值已经是不一样了。而lock_prefix的作用就是使一个指令,例如incl这样的操作在地址总线上也是原子操作的.也就是这个指令会一直的站用着地址总线,直到把v的数值写到内存中.而当地址总线锁定的时候,别的cpu压根就不能访问cpu.所以这样就从总线的站用上保证了原子.
还有就是可能有人认为在incl和sete之间不是可以被中断的吗?实际上确实是可以被中断的.但是需要清楚的是.该条指令只是说本次操作的结果是不是1,而不是用来说变量v的数值是不是0.如果你需要根据该数值进行一些操作的话,那么该函数的结果并不代表当前的变量v的真实的数值.
现在解释如下,首先说一点,任何一条汇编指令都是在一个不可分割的指令周期内完成的,也就是说,只有在指令周期内的最后一个点才回查询是否有中断发生了。现在说说lock_prefix的作用,首先想一想,因为任何的操作都在cpu的内部进行完成,所以如果想对变量v进行操作的话,那么在一个inc指令周期内,实际上cpu还是需要从内存总读出v的数值,然后对v处理之后,再写回到内存中去.这里需要注意的一个问题就是inc指令周期中,实际上发生了多次的对内存的进行访问,而这些对内存进行的访问实际上在地址总线上并不是原子操作的,也就是说.如果存在多个cpu的话,那么另外的cpu完全可以在该inc读出v的数值之后,另外的cpu这个时候就可以占用地址总线,从中读出v的数值,而这个时候,当前的cpu当修改v的数值之后,再回写到内存中,这个时候实际上就已经导致了内存的不一致的问题.因为另外的cpu的数值和真实的数值已经是不一样了。而lock_prefix的作用就是使一个指令,例如incl这样的操作在地址总线上也是原子操作的.也就是这个指令会一直的站用着地址总线,直到把v的数值写到内存中.而当地址总线锁定的时候,别的cpu压根就不能访问cpu.所以这样就从总线的站用上保证了原子.
还有就是可能有人认为在incl和sete之间不是可以被中断的吗?实际上确实是可以被中断的.但是需要清楚的是.该条指令只是说本次操作的结果是不是1,而不是用来说变量v的数值是不是0.如果你需要根据该数值进行一些操作的话,那么该函数的结果并不代表当前的变量v的真实的数值.
作者: etoux 发布时间: 2010-08-21
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28