免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
81 [报告]
发表于 2006-08-11 13:18 |只看该作者
原帖由 gvim 于 2006-8-11 12:29 发表
>>>b = a;
movl a, %eax  //1
movl %eax, b  //2

1,2之间发生中断,会发生不一致。
b = a;被分开了,何来原子?
int是高级语言中的概念,所以"int变量赋值"不是原子的。
OS理论书籍的 ...



在你举的赋值语句之间,发生中断的可能性是非常之小的,
   我的印象中,总的来说,中断为二类:1、软中断,由软件调用 int 指令实现; 2、硬件中断,又可以归纳为二类:可屏蔽的中断和不可屏蔽的中断。硬件中断需要某一条件才发生。

   基于中断类型来看,要在赋值语句之间发生中断,那么,软中断和可屏中断不太可能会发生吧。不可屏蔽中断,有一些是CPU内部产生的一些中断,如:0号除零中断,3号debug中断等,有一些是硬件中断,如:时间中断。

除零中断和debug中断就不用说了,赋值语句不会发生的。

中断指令的时钟周期远远大于mov语句,所以,赋值语句之间不太可能中断情形!

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
82 [报告]
发表于 2006-08-11 13:19 |只看该作者
要知道,在计算机的内部,概率很低的事情是经常会发生的,因为运算速度很快.

论坛徽章:
0
83 [报告]
发表于 2006-08-11 13:20 |只看该作者
to gvim,

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

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

论坛徽章:
0
84 [报告]
发表于 2006-08-11 13:20 |只看该作者
to gvim,

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

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

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
85 [报告]
发表于 2006-08-11 13:21 |只看该作者
原帖由 思一克 于 2006-8-11 13:20 发表
to gvim,

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

你说的情况在KERNEL中当然会存在。所以才有那么多锁之类的东西。而且还有注意许多可以做的和不可以做了。你可以看看KERNEL中的atomi ...


atomic 是硬件实现的.  而应用层int 赋值未必这么做.

论坛徽章:
0
86 [报告]
发表于 2006-08-11 13:27 |只看该作者
TO gvim,

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

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

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

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
87 [报告]
发表于 2006-08-11 13:27 |只看该作者
而且此类问题,在进程间切换的时候也会发生,当两个进程共享一个int 型的变量的时候.

寄存器的赋值 和 对内存的修改不能一条指令完成的时候, 就要加锁. 因为对int型的变量操作不是原子的.

这也是共享内存的时候要用信号量的原因.

论坛徽章:
0
88 [报告]
发表于 2006-08-11 13:35 |只看该作者
原帖由 mq110 于 2006-8-11 13:27 发表
而且此类问题,在进程间切换的时候也会发生,当两个进程共享一个int 型的变量的时候.

寄存器的赋值 和 对内存的修改不能一条指令完成的时候, 就要加锁. 因为对int型的变量操作不是原子的.

这也是共享内存的时 ...



加 LOCK  是用在多CPU的系统上, 另一CPU 用修改,系统shard内存, 需要LOCK,锁总线

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
89 [报告]
发表于 2006-08-11 13:44 |只看该作者
我支持 mq110 和 gvim 的说法。
不过我之前写的那个程序并不好,所以我现在不再就这个话题说什么了。

论坛徽章:
0
90 [报告]
发表于 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. }

复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP