免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
21 [报告]
发表于 2006-08-11 13:20 |显示全部楼层
to gvim,

应用程序。中断处理不是用户编的,也不会再去改被复制的变量。

你说的情况在KERNEL中当然会存在。所以才有那么多锁之类的东西。而且还有注意许多可以做的和不可以做了。你可以看看KERNEL中的atomic_t 的复制,但也没有你说的情况(我并不是十分了解)。比如在时钟中断中去故意修改KERNEL中的某些全局atomic,会如何?

论坛徽章:
0
22 [报告]
发表于 2006-08-11 13:20 |显示全部楼层
to gvim,

应用程序。中断处理不是用户编的,也不会再去改被复制的变量。

你说的情况在KERNEL中当然会存在。所以才有那么多锁之类的东西。而且还有注意许多可以做的和不可以做了。你可以看看KERNEL中的atomic_t 的复制,但也没有你说的情况(我并不是十分了解)。比如在时钟中断中去故意修改KERNEL中的某些全局atomic,会如何?

论坛徽章:
0
23 [报告]
发表于 2006-08-11 13:27 |显示全部楼层
TO gvim,

一个
i = j; 语句是这样的

0x08048379 <func1+3>:   mov    0x8049584,%eax
0x0804837e <func1+8>:   mov    %eax,0x8049588

在多THREAD的程序中原子性有问题吗?两个mov之间中断也没有问题吧。系统调度更没有问题。关键是你可以写一个可以证明出问题的程序演示出来。

论坛徽章:
0
24 [报告]
发表于 2006-08-11 14:01 |显示全部楼层
这个程序也是来自flw的改动。在SERVER永远不停。只要用不原子的情况就有输出,否则就什么也不说。
可以监视1个月。

再有看这样监视是否合理,还有更好的改进?



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

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

  7. #define TEST1

  8. void *incCount( int id );

  9. int main( void )
  10. {
  11.     pthread_t thread;
  12.     int i;
  13.     int ret;

  14.     for( i=0; i<6; i++ ){
  15.         ret = pthread_create( &thread, NULL, (void *(*)(void *))incCount, (void *)i );
  16.         if ( ret != 0 ){
  17.             perror( "pthread_create" );
  18.             exit(-1);
  19.         }
  20.     }
  21.     while(1) sleep(100);

  22.     return 0;
  23. }


  24. void *incCount( int id )
  25. {
  26.     int i;
  27.     unsigned int k, v;
  28.     id++;
  29.     k = 0x11111111*id;
  30.     printf( "Hello, I am pthread %d\n", id );
  31.     while(1){
  32.         for( i=0; i<10000; i++ ){
  33.             count = k;
  34.             v = count;
  35.             if((v & 0x0000ffff) != (v >> 16)) {
  36.                 printf("%p %p\n", v, count);
  37.             }
  38.         }
  39.     }

  40.     printf( "[%d] Done.\n", id );
  41.     return NULL;
  42. }

复制代码

论坛徽章:
0
25 [报告]
发表于 2006-08-11 15:57 |显示全部楼层
原子性就是从使用者角度不用加琐来保证数据的一致性。
至于中间是否有中断打断不用管。

谈系统调用的原子性就是这含义。比如write,有数百上千汇编指令,但在许多时候都可以说是原子的。

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

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

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

论坛徽章:
0
27 [报告]
发表于 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
28 [报告]
发表于 2006-08-14 11:46 |显示全部楼层
我找到SMP(2个CPU),运行结果也是和单个CPU一样

论坛徽章:
0
29 [报告]
发表于 2006-08-21 08:43 |显示全部楼层
to oyscal,

global_var++被翻译成为INC GV, 和赋值不是一个语句。赋值是原子的,在SMP多CPU中也是原子的。INC在SMP中不是原子的。你说的是正确的,但忽略了关键

[ 本帖最后由 思一克 于 2006-8-21 08:44 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP