能力值:
( LV2,RANK:10 )
|
-
-
2 楼
有点原子操作是通过cpu的指令完成的,自加、自减、赋值都可以用专门的cpu指令一步到位。因为只有一个指令,无论线程如何切换,都不会被切成两半,所以是“原子操作”。
复杂的原子操作可以通过加锁来完成,单CPU上直接提高自身的中断级别到没有线程切换的级别就行,多CPU下需要使用自旋锁。
|
能力值:
( LV7,RANK:110 )
|
-
-
3 楼
原子操作,顾名思义,不可分割
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
膜拜2楼的解答啊.........
|
能力值:
( LV6,RANK:90 )
|
-
-
5 楼
你说的原子操作是在单CPU上的,现在是要考虑多核情况,举个例子:
1 2 3 4 5 6 7 8 9 | int main(int argc, char **argv)
{
volatile int a;
a = a+1;
a++;
return 0;
}
|
gcc 生成的汇编代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 | pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl -4(%ebp), %eax
addl $1, %eax
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
addl $1, %eax
movl %eax, -4(%ebp)
movl $0, %eax
leave
ret
|
先不考虑中断和线程的切换,可以看出自加和直接赋值加1生成的 汇编代码一样,都有三步,第一,从内存取值movl -4(%ebp), %eax,第二,给值加1,addl $1, %eax,第三,把值放回内存,如果不锁内存总线的话,第一个CPU取值再寄存器里给值加1的时候,第二个CPU 接管了内存总线,同样的取值修改,那么最后看到的值就发生错乱了,所以我认为自加,在不锁内存总线的情况下,在多核中,不能 保证是原子操作。这个是多核CPU并发竞争的问题,而你说的是异步的问题,
至于你说 的自悬锁 其内部也是用 原子操作函数对锁计数加减来完成的,所以,自悬锁,从某种意义上来说,也依赖于 原子操作。
记得以前在翻wrk时,微软提供的 interlockincrement,,,,等等系列的函数,实现时也是用汇编指令加lock前缀实现的。
至于汇编指令的 inc dec等,在单核下是原子操作,但在多核下就不敢保证了。。。
个人愚见,忘不吝指正
|
能力值:
( LV5,RANK:70 )
|
-
-
6 楼
我估计你看的是未开启smp的代码吧,为开启的时候,就是普通的变量操作,
开启smp的时候,代码是根据不同的处理器使用的原子操作,比如lock前缀
|
|
|