多处理器编程的艺术 第3章 并发对象

3.3 静态一致性
      + 如果一个方法的调用事件已经发生,但其响应事件还未发生,则这个方法调用
      是未决的。
      + 若一个对象中不存在未决(pending)的方法调用,则该对象是静态的。
      - 静态一致性,是指在任一时刻若对象变为静态的,那么到此刻为止的执行等价于
      目前已经完成的所有方法调用的某种顺序执行。
      
      静态一致性:
       原则3.3.1 方法调用应呈现出以某种顺序次序执行且每个时刻只有一个调用发生。
       原则3.3.2 由一系列静止状态分隔开的方法调用应呈现出与按照它们的真实的调用
        次序相同的执行效果。
     - 在并发执行中,对于完全方法的任何一个未决调用,都必存在一个静态一致的响应。
     - 静态一致性是可复合的,也是一种非阻塞的正确性条件。
3.4 顺序一致性
      + 一个单线程的方法调用次序称为该线程的程序次序。
      原则 3.4.1 方法调用应该呈现出按照某种顺序次序的执行效果。
      
      - 顺序一致性要求方法调用的执行行为具有按照某种顺序次序的执行效果,
      并且这种顺序执行的次序应该与程序次序保持一致。就是说,在任意的并发执行
      中,都存在着一种办法能使得方法调用按照某种顺序次序排序,并且这种顺序次序
      1> 与程序次序相一致 2> 满足对象的顺序规范说明。
       以上,可以用来判断执行是否是顺序一致的。
       
3. 5 可线性化性

-  When defining a correctness condition for concurrent objects, two requirements
   seem to make intuitive sense: First, each operation should appear to “take effect”
   instantaneously,  and second, the order of nonconcurrent    operations should be
   preserved.
        
-   Processes are sequential: each process applies a sequence
of operations to objects, alternately issuing an invocation and then receiving the
associated response. (Dynamic process creation can be modeled simply by treating
each child process as an additional process that executes no operations before
the fork or after the join.)

-  A history H is sequential if:
(1) The first event of H is an invocation.
(2) Each invocation, except possibly the last, is immediately followed by a
    matching response. Each response is immediately followed by a matching
    invocation.
A history that is not sequential is concurrent.

-    A sequential history H is legal if each object subhistory H | x belongs to the sequential specification
     for x.  
以上内容参考:Linearizability: A Correctness Condition for Concurrent Objects
               MAURICE P. HERLIHY and JEANNETTE
               Carnegie Mellon University

- 可线性化的判断:


 

-  是否可线性化的判断的实例:


 


 


- 可线性化的性质:

  * 可线性化是可复合的:
     定理 3.6.1 对于每个对象x,当且仅当H|x是可线性化的,H是可线性化的。
     
     复合性是个重要的特性, 它使得并发系统的设计和构造能够采用模块化的方式,
     不同的可线性化对象可以独立地实现、验证和执行。
  * 非阻塞特性:
      + 如果一个方法对对象的所有状态都给出了定义,则称该方法是完全的。
     可线性化是一种非阻塞特性: 一个完全方法的未决调用不需要等待另一个未决调用
     完成。
    定理3.6.2  令inv(m)是完全方法的一个调用。如果<x inv P> 是可线性化经历 H中的一个

    未决调用,则必定存在一个响应<x res P>使得 H·<x res P>是可线性化的。

 3.7 演进条件(Progress Conditions)         
  -    Such an implementation is called blocking, because an unexpected delay by one
        thread can prevent others from making progress.

   - A method is wait-free if it guarantees that every call finishes its execution in a finite number of steps.
     *  Being wait-free is an example of a nonblocking progress condition, meaning that an arbitrary and
       unexpected delay by one thread (say, the one holding a lock) does not necessarily prevent the
        others from making progress.

    Example of 'Wait Free'
     class WaitFreeQueue<T> {
        volatile int head = 0, tail = 0;
        T[] items;
        public WaitFreeQueue(int capacity) {
          items = (T[])new Object[capacity];
          head = 0; tail = 0;
        }
        public void enq(T x) throws FullException {
          if (tail - head == items.length)
            throw new FullException();
          items[tail % items.length] = x;
          tail++;
        }
        public T deq() throws EmptyException {
          if (tail - head == 0)
            throw new EmptyException();
          T x = items[head % items.length];
          head++;
          return x;
        }
     }
Figure 3.3 A single-enqueuer/single-dequeuer FIFO queue.  

 Example of  'Not Wait Free'
   class LockBasedQueue<T> {
     int head, tail;
     T[] items;
     Lock lock;
     public LockBasedQueue(int capacity) {
       head = 0; tail = 0;
       lock = new ReentrantLock();
       items = (T[])new Object[capacity];
     }
     public void enq(T x) throws FullException {
       lock.lock();
       try {
         if (tail - head == items.length)
           throw new FullException();
         items[tail % items.length] = x;
          tail++;
       } finally {
         lock.unlock();
       }
     }
     public T deq() throws EmptyException {
       lock.lock();
       try {
         if (tail == head)
           throw new EmptyException();
         T x = items[head % items.length];
         head++;
         return x;
       } finally {
         lock.unlock();
       }
     }
   }
 
-    A method is lock-free if it guarantees that infinitely often some method call finishes in a finite number
     of steps.

Lock-free 算法的基础是 CAS (Compareand-Swap) 原子操作。当某个地址的原始值等于某个比较值时,把值改成新值,无论有否修改,返回这个地址的原始值。目前的cpu 支持最多64位的CAS。并且指针 p 必须对齐。

 注:原子操作指一个cpu时钟周期内就可以完成的操作,不会被其他线程干扰。

一般的 CAS 使用方式是:

假设有指针 p, 它指向一个 32 位或者64位数,

   1.
      复制p 的内容(*p)到比较量 cmp (原子操作)
   2.
      基于这个比较量计算一个新值 xchg (非原子操作)
   3.
      调用 CAS 比较当前 *p 和 cmp, 如果相等把 *p 替换成 xchg (原子操作)
   4.
      如果成功退出,否则回到第一步重新进行

第3步的 CAS 操作保证了写入的同时 p 没有被其他线程更改。如果*p已经被其他线程更改,那么第2步计算新值所使用的值(cmp)已经过期了,因此这个整个过程失败,重新来过。多线程环境下,由于 3 是一个原子操作,那么起码有一个线程(最快执行到3)的CAS 操作可以成功,这样整体上看,就保证了所有的线程上在“前进”,而不需要使用效率低下的锁来协调线程,更不会导致死锁之类的麻烦。//参考 http://blog.csdn.net/arau_sh/article/details/6636371
+  We say that a method call executes in isolation if no other threads take steps.
- Definition 3.7.1. A method is obstruction-free if, from any point after which it
   executes in isolation, it finishes in a finite number of steps.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值