免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
171 [报告]
发表于 2006-08-12 22:53 |只看该作者
还没争完????
其实就一句话:
CPU不会在一条指令执行期间响应任何中断,其余自己想想就完了。

论坛徽章:
0
172 [报告]
发表于 2006-08-12 23:10 |只看该作者
原帖由 mik 于 2006-8-12 21:09 发表
呵呵~~ 若你没记错的话,那就更能说明为什么要在多CPU系统中锁总线了。


锁总线的性能是不能接受的!
现在的基于共享存储的UMA SMP设计,都是使用CACHE来回避总线占用,并采用特定手段解决缓存一致性的问题。

实际上这个帖子的主题根本牵扯不到这个问题。
~~~~ 该用户已被删除
173 [报告]
发表于 2006-08-13 07:15 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
~~~~ 该用户已被删除
174 [报告]
发表于 2006-08-13 07:16 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
175 [报告]
发表于 2006-08-13 12:48 |只看该作者
支持whyglinux的观点~

int赋值操作,不管被分解成多少个汇编指令,只要保证仅有一条指令,完成对目标操作数(即多个线程共享那个变量)的访问,那么这个赋值过程就是原子的,因为那个写操作数的指令是不会被打断的。  

赋值操作中的其余指令只不过是一些辅助操作,比如从局部变量MOV到寄存器,这些操作被中断不会影响整个操作的原子性(因为有现场保护)。

论坛徽章:
0
176 [报告]
发表于 2006-08-13 20:53 |只看该作者
我觉得一个操作是否原子, 要看该操作是否需要多次使用数据总线. 而不是几条指令.

大多数int赋值(立即数)只要一次memory cycle. 是原子的. 另外象 a=b 或 a++, 也许只要一条指令, 但必需读写两个memory cycle, 不是原子的, 需要加锁.

现在的CPU向多核发展, 同步是很重要的. 但code不能依赖某些硬件的实现, 先要保证正确.

论坛徽章:
0
177 [报告]
发表于 2006-08-14 08:57 |只看该作者
在INTELX86 LINUX 单CPU下(根据LINUX atomic.h代码可以推断在许多其它平台也一样),
应用程序的全局int的读写(无论多thread,还是多PROCESS的shmem)都是原子的。不需要LOCK,放心地使用吧。

此时,C变为一条还是多条汇编无关,原因前面说过了。

多SMP下最好有人帮实验一下。

论坛徽章:
0
178 [报告]
发表于 2006-08-14 09:23 |只看该作者
这个程序哪位在SMP LINUX机器上帮运行一下。

gcc -lpthread atomic.c -o testa
./testa      没有参数就是用原子复制
./testa X   有任何参数就是故意不用原子复制

如果不是原子的,程序会退出,否则一直跑。还可以观察到count被其它THREAD改了的情况



  1. # include <stdio.h>
  2. # include <stdlib.h>
  3. # include <pthread.h>
  4. # include <unistd.h>

  5. int not_atomic = 0;
  6. int runFlag = 1;
  7. int count = 0;

  8. void *testa( int id );

  9. int main( int argc, char **argv )
  10. {
  11.     pthread_t thread;
  12.     int i, ret;

  13.     if(argc > 1 && argv[0][0]) not_atomic = 1;

  14.     for( i = 0; i < 8; i++ ){
  15.         ret = pthread_create( &thread, NULL, (void *(*)(void *))testa, (void *)i );
  16.         if ( ret != 0 ){
  17.             perror( "pthread_create" );
  18.             exit(-1);
  19.         }
  20.     }
  21.     while(runFlag) sleep(5);
  22.     return 0;
  23. }


  24. void *testa( int id )
  25. {
  26.     int i;
  27.     unsigned int k, v;

  28.     k = 0x11111111*id;
  29.     while(runFlag){
  30.         for( i=0; i<10000; i++ ){
  31.            if(not_atomic == 0) {
  32.                 count = k;
  33.            } else {
  34.                 ((short*)&count)[0] = ((short*)&k)[0];
  35.                 ((short*)&count)[1] = ((short*)&k)[1];
  36.            }
  37.            if(count != k)
  38.                 printf("%08x %08x\n", k, count);

  39.            v = count;
  40.            if((v & 0x0000ffff) != (v >> 16)) {
  41.                 printf("NOT ATOMIC VALUE FOUND: %p %p\n", v, count);
  42.                 runFlag = 0;
  43.            }
  44.         }
  45.     }
  46.     return NULL;
  47. }

复制代码

论坛徽章:
0
179 [报告]
发表于 2006-08-14 11:46 |只看该作者
我找到SMP(2个CPU),运行结果也是和单个CPU一样

论坛徽章:
0
180 [报告]
发表于 2006-08-15 11:26 |只看该作者
楼主的问题是不是可以改成:
对于各种CPU来说,中断请求的优先级以及**是否**允许中断的条件判断都是怎么样的. 另外该CPU对延时处理都采用什么方式?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP