免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
91 [报告]
发表于 2006-08-11 14:16 |只看该作者
原帖由 gvim 于 2006-8-11 13:07 发表
这不是复杂不复杂的问题。即便在up上也如此。

如果a ,b 都是系统级的全局变量
a=10;
b=a;
movl a,%eax   #1
movl %eax, b  #2

1) 进程x 在#1, #2之间发生中断,切换到其他程序y。%eax现在是10,被自动保存。
2) y赋值b=20
3) 切换回x
4) x执行#2句,取出%eax的值10,付给b。
那么,b到底应该是x赋的10还是y赋的20?

问题在于,你能保证#1,#2之间不会发生中断?


对于代码(#3表示任何操作 a 或者 b 的语句):

  1. a=10;
  2. b=a;
  3. movl a,%eax   #1
  4. movl %eax, b  #2
  5. movl x, x     #3
复制代码

来说,不管 #1 和 #2 之间可能发生中断还是 #1 和 #2 之间不会发生中断,对于 #3 来说都是一样的,即:
  • 不能认为 b 的值就是 10
  • 不能认为 a 的值仍然是 10

因为就算 #1 和 #2 构成原子操做,中间不会被打断,也无法保证 #2 和 #3 之间不会发生中断。对于 #3 来说,a 和 b 的值总是可能会被中断程序修改。

论坛徽章:
0
92 [报告]
发表于 2006-08-11 14:27 |只看该作者
原帖由 isjfk 于 2006-8-11 14:16 发表


对于代码(#3表示任何操作 a 或者 b 的语句):

  1. a=10;
  2. b=a;
  3. movl a,%eax   #1
  4. movl %eax, b  #2
  5. movl x, x     #3
复制代码

来说,不管 #1 和 #2 之间可能发生中断还是 #1 和 #2 之间不会发生中 ...



我认为: 对共用的存储区,有可能被修改,对私用的存储区不会被修改.

论坛徽章:
0
93 [报告]
发表于 2006-08-11 14:31 |只看该作者
原帖由 mik 于 2006-8-11 13:18 发表



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

这个问题不能用可能性非常小来解释。而是在这种并不友好的硬件机制上实现多进程的一致性是可行的。随便找一本 OS 原理书都有这方面的论述。

论坛徽章:
0
94 [报告]
发表于 2006-08-11 14:37 |只看该作者
原帖由 isjfk 于 2006-8-11 14:31 发表

这个问题不能用可能性非常小来解释。而是在这种并不友好的硬件机制上实现多进程的一致性是可行的。随便找一本 OS 原理书都有这方面的论述。
原帖由 mik 于 2006-8-11 14:27 发表

我认为: 对共用的存储区,有可能被修改,对私用的存储区不会被修改.

是的。对于用一个变量协调两个进程的同步情况来说,就要做这个假设,即只有需要进行协调的两个进程可以修改这个变量。这样就可以肯定这个变量里的值不是 A 进程赋的值,就是 B 进程赋的值。在这个理论基础上可以实现两个进程的同步。如果有第三个进程干扰,同步肯定失败。

论坛徽章:
0
95 [报告]
发表于 2006-08-11 14:45 |只看该作者
呵呵~ 这个贴子的许多言论都是属于纸上谈兵类~

要做到令人信服, 恐怕要深入细致地了解系统对多线程,多进程的实现, 并能举出例子, 还有一个可行的分析、调试的方法

论坛徽章:
0
96 [报告]
发表于 2006-08-11 14:53 |只看该作者
弱弱地问一句:什么是原子的?
你们争论的让人觉得似乎不是同一个问题。

系统调用是原子的吗?

另外,思一克版主在第9页的程序思路也有些问题:
count = k;
v = count;
if((v & 0x0000ffff) != (v >> 16)) {
这个不等,恐怕只会出现在按字节赋值等情况下(比如51单片机等int与地址位数不等)----无论count被怎么改,无论v被怎么改,最后v肯定属于0x11111111*[1,6],v & 0xffff 肯定 等于v>>16.

论坛徽章:
0
97 [报告]
发表于 2006-08-11 14:54 |只看该作者
原帖由 mik 于 2006-8-11 14:45 发表
呵呵~ 这个贴子的许多言论都是属于纸上谈兵类~

要做到令人信服, 恐怕要深入细致地了解系统对多线程,多进程的实现, 并能举出例子, 还有一个可行的分析、调试的方法

是呀。不过这看起来并不妨碍一群人讨论的热情

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
98 [报告]
发表于 2006-08-11 14:57 |只看该作者
原帖由 assiss 于 2006-8-11 14:53 发表
弱弱地问一句:什么是原子的?
你们争论的让人觉得似乎不是同一个问题。

系统调用是原子的吗?

另外,思一克版主在第9页的程序思路也有些问题:

我也觉得好像不是一个问题。

论坛徽章:
0
99 [报告]
发表于 2006-08-11 15:02 |只看该作者

论坛徽章:
0
100 [报告]
发表于 2006-08-11 15:04 |只看该作者
原帖由 mq110 于 2006-8-11 13:11 发表
在操作系统的基本课程中早就提到过了 ,

int变量的赋值操作如果翻译成汇编语句不是单条指令的话,那么肯定不是原子的.


一个 C 语句通常对应着一条或者多条指令。如果对应着多条指令,那么这个赋值操作就有可能从中间被中断,这时可以说赋值操作不是原子的。这是一种从指令集角度上的理解。

还可以有另外一种理解,即从赋值操作的实际效果上来考虑问题:只要不会出现楼主所说的部分赋值现象,我们就可以说赋值是原子操作。为此,可以把赋值操作的指令集分为两部分:赋值准备指令和写指令(如果是立即数的赋值可能不需要赋值准备指令)。显然,如果写指令只有一条的话,赋值操作是原子的;否则,写指令多于一条的话就不能保证赋值操作的原子性了。

楼主所提问的应该是后一种理解,也应该是一般意义上的理解。

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

如果是这样的话,就无法解释在一些平台上出现的 思一克 所说的下面的情况:
  1. 看atomic_t的定义,就定义为一个整数。
  2. atomic_set()和atomic_read()就是一个赋值汇编语句。没有用lock.
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP