Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4282494
  • 博文数量: 241
  • 博客积分: 15936
  • 博客等级: 上将
  • 技术积分: 25293
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-27 11:22
个人简介

Fedora-ARM

文章分类
文章存档

2016年(3)

2014年(1)

2013年(3)

2012年(50)

2011年(61)

2010年(26)

2009年(27)

2008年(21)

2007年(49)

分类: LINUX

2007-03-28 09:05:39

原子性

   原子性这个概念初想是非常简单的。它表示一个操作序列就像一个操作一样不被打断,而不像一个操作序列一样中间容许被打断。但是细想下来还是挺有点意思的。首先需要确定的就是什么是一个操作?而什么不是一个操作却是一个操作序列?其次需要确定的是如何叫做像?怎么着就是不像了?另外,还有一个牵扯进来的概念就是原子性的范围和其在什么程度上实施这种保证。或许我这儿说的有点形而上,那我们就形而下的举出例子抓住原子性这个概念的直观感觉。
先举一个CPU指令集中常见的一个指令:CAS。看到这个指令我就仿佛看到了大家脸上的某种意味的笑容。呵呵,是的,它完成两个操作,一个比较,一个交换,后一个完不完成依赖于前一个操作的结果,从逻辑上说,它们是两个操作,可是它们特意被实现为不可打断的。这就是一个经典的原子指令。我们分析一下,这里面什么是我们前文提到的操作,什么是操作序列?什么是不容打断性?其实现的范围如何?其实现在什么程度上能保证不被打断?比较和交换是上文提到的操作,它们的逻辑顺序组合式操作序列,CPU在硬件级别实施了不容打断性,由于CPU级别实现了这种不容打断性,那么在整个计算机系统中其不容打断性都得到了保证,也就是说,这种不容打断性实现的范围是全系统。只要计算机没有断电,器件正常而且正常运行,这种不容打断性就是能够保证的。显然,计算机在执行该原子操作的一般的时候突然断电,并不能保证原子性了。这就是该原子性的保证强度,可以说是比较强的。尤其是我们假设把计算机系统定义为run machine的时候,可以说在全系统的范围都能得到强保证。
看到这儿,我们总希望深入一步,CPU是如何实施这种保证的。虽说我并不想探讨这个技术细节的问题(一般情况下,我更愿意探讨概念而不是细节,原因是概念不变而物理实现细节恒变),但是还是有某些要求导致我需要探讨物理实现。
CPU 首先把这个操作序列实现为一条指令,然后采用某种措施保证该指令执行期间不会被打断,一般情况下这种保证措施是总线的占据而不释放。有时候有些人愿意把这个叫做总线锁定。这就是实现方式,我不想更进一步的深入到如何锁定总线而不释放,如果有兴趣知道,参见相关的硬件文档。
通常情况下,与我们而言,我们要求更高级更符合我们需求的原子性,而不是CPU级别实现的原子性。最明显的例子就是信号量相关P、V操作。P、V操作要求是原子性的。也就是说,无论是P(一直等到有信号状态,然后置成无信号状态,用语言描述就是while (s == 0) {wait}; s = s - 1),还是V(置成有信号状态s = s + 1),都要保证其过程不被打断。这时候,我们就是依赖于CPU给我们提供的原子性保证,来实现我们这个相对来说更高级一点的原子性的操作序列。它是如何实现的并不是我们关注的焦点,我们还是想要分析一下这个所谓的P、V原子性操作序列的实现特质。我们分析一下,这里面什么是我们前文提到的操作,什么是操作序列?什么是不容打断性?其实现的范围如何?其实现在什么程度上能保证不被打断?第一个个问题似乎跟具体实现有关系,我们不深入讨论什么是其操作步骤了,操作序列显然就是P或者V本身的所有操作。它们的实现不容被打断。这没什么可说的,但我们马上就遇到了真正有趣的问题的,实现范围!在什么范围内起保证不被打断?在整个计算机系统?在一个进程中?或者还有什么别的范围?显然,这是一个问题。这里我并不想给出一个具体的说法,因为显然可以有很多说法。那么,其实现在什么程度上保证不被打断呢?显然,这个问题跟实现范围的问题有所纠缠,如果其实现范围是全系统,那么在整个计算机系统的任意时间内,P、V操作都保证不被打断,而如果其实现范围是进程,那么在该进程活动步骤中,P、V操作保证不被打断,但并不保证进程不会在正在执行P或者V操作的时候被打断而切换到另一个进程中。更不要说计算机系统因故停机对它们的打断了。
从上面的两个形而下的例子中,我们是不是能比较清晰的给出一个关于“如何叫做像?怎么着就是不像了?”的一个答案了。
最初我们的定义是其实现就是一个不容打断的操作序列,现在我们看到,只要在某种范围和程度上,看起来这个操作序列没有被打断就行了。这就使所谓的“像是没有被打断”的真实含义。
下面我还想更进一步讨论一下关于数据库事务中的原子性问题。
数据库事务中的原子性,可以用要么全做,要么不做来概括。看出来了么?它其实是上面原子性的目的。所以我们把数据库中的事务的这个特性叫做原子性是相当切题的。但是它似乎跟我们所说的原子性有点微妙的区别。这是真的么?
其实我们还可以用上面的范围和程度等来分析数据库事务中的原子性的特征。这儿我就把它当成一个练习留给读者了。我想顺带提一下的是:对于分布式数据库事务的两阶段提交这个非常出名和非常聪明的保持原子性的办法,是(似乎是)Jim Cray提出来的,他现在在Microsoft工作,而Microsoft的DTC可以说是分布式事务实现的鼻祖。看来我们也不能太看扁了 Microsoft:)。
现在我们是否可以回答原子性究竟是什么了呢?我打开门把你们迎接进来,却没有告诉你们正确的出口,这个答案得你们自己找。祝你们好运。

阅读(8403) | 评论(2) | 转发(10) |
给主人留下些什么吧!~~

chinaunix网友2010-08-16 15:16:38

代码中LOCK_PREFIX首先会锁住总线,然后操作就可以保证原子性了。

wojiaohesen2008-04-10 12:26:55

哥们,我问个问题,像atomic_inc_and_test这样的函数,如何保证它的实现在内核是原子性的呢》它的定义如下: static __inline__ int atomic_inc_and_test(atomic_t *v) { unsigned char c; __asm__ __volatile__( LOCK_PREFIX "incl %0; sete %1" :"+m" (v->counter), "=qm" (c) : : "memory"); return c != 0; } 难道它不能被打断吗?谢谢