免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
11 [报告]
发表于 2006-08-11 16:46 |显示全部楼层
原帖由 gvim 于 2006-8-11 16:17 发表


你是怎么加锁的?

我得意思是
lock();
b = i;
unlock();

lock()
movl i, %eax
movl %eax, b
ulock()

不错,if 仍然会发生,不过那是@34和@45的情况了,而不是@23的情况。
对于原子性,在执 ...



请问:这个lock()怎么实现呢?

论坛徽章:
0
12 [报告]
发表于 2006-08-11 16:51 |显示全部楼层
原帖由 mq110 于 2006-8-11 16:48 发表


多进程是信号量实现的。


这就与LZ所讨论的问题离题千里

论坛徽章:
0
13 [报告]
发表于 2006-08-11 23:34 |显示全部楼层
原帖由 gvim 于 2006-8-11 23:08 发表


我到第一次听说原子性还可以从过程和结果两种方式去理解。

如你说所,过程不是原子的已经达成共识。

那么我第二次问你“赋值结果”是什么意思?
你的意思是否是 重点在最后的往左操作数b写入的 movl % ...


你所认同的原子操作是 CPU 的调度单位,是一条指令的执行,

他们认同的原子操作是 OS 的调度单位,也就是利用信号量,临界点等手段来保证操作的执行。

论坛徽章:
0
14 [报告]
发表于 2006-08-12 00:02 |显示全部楼层
原帖由 gvim 于 2006-8-11 23:51 发表


整篇帖子的讨论 什么时候又把信号量,临界点拖出来了?真是莫名其妙。
"int变量的赋值" 你认为是OS在为变量赋值吗?真是答非所问。
有人说把一条赋值语句分成N条指令后仍然是原子的,但是我的论点 ...





[ 本帖最后由 mik 于 2006-8-12 00:34 编辑 ]

论坛徽章:
0
15 [报告]
发表于 2006-08-12 10:42 |显示全部楼层
原帖由 flw2 于 2006-8-12 10:36 发表
movl $0,%eax
也不是原子的.


为什么这么说呢?

论坛徽章:
0
16 [报告]
发表于 2006-08-12 10:49 |显示全部楼层
原帖由 flw2 于 2006-8-12 10:45 发表


为什么是原子的?


这条指令还能拆分吗?

这个话题已经没什么好讨论的了,只是在这里灌灌水,我STOP了:wink:

论坛徽章:
0
17 [报告]
发表于 2006-08-12 15:45 |显示全部楼层
回163楼, 忍不住,又插一句:

闲着没事可做,没什么别的意途。

111 楼那程序并不能说明什么, 我将 111 楼那个程序的 inc_count2() ,加了几条 printf() 语句


  1. void * inc_count2(int id)
  2. {
  3.        while(1) {
  4.                 printf("i = %d\n, i);                /*    #1     */
  5.                 printf("d = %d\n",d);             /*    #2    */


  6.                 i = 50;
  7.                 b = i;
  8.                
  9.                 printf("i = %d\n", i);             /*    #3     */
  10.                 printf("d = %d\n",d);           /*     #4     */
  11.                
  12.                 if (b != i) {
  13.                          printf("crashed\n");
  14.                          exit(1);
  15.                 }
  16.        }
  17. }
复制代码


结果是:

  1. i = 10
  2. b = 0
  3. ... ...

  4. i=50
  5. b=50
  6. i = 50
  7. b = 50

  8. ... ...

  9. crashed
复制代码


在第1,2条 printf 输出了 i = 10  b = 0 的结果
在第2第printf 到 最后 crashed 信息输出之间全都是

i = 50
b = 50


说明:在两2条 printf() 和 printf("crashed\n" 语句之前,i 和 b 是相等的,
      经过一些时间后,出现了不相等情况,那是在第4条 printf() 语句之后的事情了。
      i = 50;  b = i;  这两条赋值语句并没有被中断

      那么,这里是否可以初步认为,这两条赋值语句的具有原子性呢

论坛徽章:
0
18 [报告]
发表于 2006-08-12 15:47 |显示全部楼层
说过 STOP 了,又发一贴,罪过罪过,佛祖别惩罚我

[ 本帖最后由 mik 于 2006-8-12 15:52 编辑 ]

论坛徽章:
0
19 [报告]
发表于 2006-08-12 20:37 |显示全部楼层
原帖由 flw2 于 2006-8-12 10:36 发表
movl $0,%eax
也不是原子的.



flw2,  我仔细琢磨一下。你所说的还是有一定的道理的。

movl $0, %eax  这句指令应该是原子性的。因为它没有存/取内存的行为。

但:
movl %eax, a  这一条指令,是不能保证它一定是原子性的。

CPU 要将数据存放在内存,必须经过地址总线传递。


考虑以下的一种情况:

在多CPU系统中, CPU 发出指令 要将 eax 数据往 [a] 这个内存里放,经过地址总线,

而正好,另一个CPU 抢先把地址总线占了,那么,第一个CPU 执行的指令应该先被挂起,直至地址总线空闲了,它才可以继续执行写内存的操作。

所以。在多CPU系统里,只有加LOCK了,才能保证其一定是原子性的。

象存/取内存的指令前,应加上:  lock movl %eax, a


然而,在单CPU系统中,一条指令我认为应该是原子性的。

论坛徽章:
0
20 [报告]
发表于 2006-08-12 21:09 |显示全部楼层
原帖由 isjfk 于 2006-8-12 21:05 发表
多 CPU 的时候也是跟多 CPU 的架构有关系。我记得早期的 486 多处理器,如果一个 CPU 执行的指令需要访问内存,则 CPU 会在这条指令的始终周期内始终占用内存总线。



呵呵~~ 若你没记错的话,那就更能说明为什么要在多CPU系统中锁总线了。

写内存指令是要超过一个周期滴
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP