`
eriol
  • 浏览: 407244 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

lock-free线程安全算法

    博客分类:
  • OS
阅读更多

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

 

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

 

 

一般的 CAS 使用方式是:

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

其中,第3步的 CAS 操作保证了写入的同时 p 没有被其他线程更改。如果*p已经被其他线程更改,那么第2步计算新值所使用的值(cmp)已经过期了,因此这个整个过程失败,重新来过。多线程环境下,由于 3 是一个原子操作,那么起码有一个线程(最快执行到3)的CAS 操作可以成功,这样整体上看,就保证了所有的线程上在“前进”,而不需要使用效率低下的锁来协调线程,更不会导致死锁之类的麻烦。

 

 

lock-free的优点:

 

一个“锁无关”的程序能够确保执行它的所有线程中至少有一个能够继续往下执行。这便意味着有些线程可能会被任意地延迟,然而在每一步都至少有一个线程能够往下执行。因此这个系统作为一个整体总是在“前进”的,尽管有些线程的进度可能不如其它线程来得快。而基于锁的程序则无法提供上述的任何保证。一旦任何线程持有了某个互斥体并处于等待状态,那么其它任何想要获取同一互斥体的线程就只好等待;一般来说,基于锁的算法无法摆脱“死锁”或“活锁”的阴影。

 

 

ABA 问题

 

如果当 A 线程执行2的时候,被B 线程更改了 *p为x, 而 C 线程又把它改回了原始值,这时回到A 线程,A线程无法监测到原始值已经被更改过了,CAS 操作会成功(实际上应该失败)。ABA 大部分情况下会造成一些问题,因为 p 的内容一般不可能是独立的,其他内容已经更改,而A线程认为它没有更改就会带来不可预知的结果。

 

ABA 问题的解决一般是扩展 *p 的位数(比如从32扩展到64),使用多余的位来保存一个版本号,每次更改都修改版本号,从而保证这个线程能正确的监测到值的更改。

 

 

扩展

 

一个 32 位数无法携带太多信息,但是32位的C++ 环境中,这样的一个数已经可以代表很多东西了,比如——指针。

 

我们刚才保证了我们的线程可以安全读写一个 32 位的数,如果这个数是一个指针,指向了我们真实使用的对象。那么我们就可以创建了一个无锁而线程安全的对象。基本思想就是每次修改对象前,复制整个对象,然后更改完成以后用上面的算法使用新对象来替换旧对象(更改p的指向),当然,这个对象不能太大,否则lock-free的速度优势,就被复制操作消耗殆尽。

 

这里有个很大的问题,在于老的对象何时销毁。P 指向新的对象了,以后的操作都将会访问新的对象,但是老的对象还可能正被其他线程访问中。遗憾的是,我们还没有垃圾收集器,所以需要设计一个引用计数之类的策略来保护这个对象。

 

 

原文地址:http://blog.csdn.net/jadedrip/article/details/1731554

分享到:
评论

相关推荐

    自扩充的Lock-Free并发环形队列算法

    【自扩充的Lock-Free并发环形队列算法】 在并发编程中,环形队列是一种常用的结构,尤其在多线程环境和实时系统中。它允许高效的数据传递,因为其首尾指针间的循环特性避免了数组类型的越界问题。然而,固定大小的...

    lock-free-wait-free-circularfifo.zip_Free!_可等待fifo_环形FIFO

    - Wait-free算法通常更复杂,因为它需要考虑到所有可能的并发执行路径,以确保每个线程都能独立完成其操作。 3. **可等待FIFO**: - 在某些情况下,lock-free和wait-free并不总是最佳选择,因为它们可能增加代码...

    Lock-Free Data Structures

    “锁自由”(Lock-Free)是指一种多线程编程技术,它避免了使用传统的锁机制来同步共享资源的访问。在经典基于锁的多线程编程中,当多个线程需要访问同一份数据时,通常会通过加锁来确保数据的一致性和完整性。例如...

    Lock-free Queue and Ring Buffer

    无锁队列与环形缓冲区(Lock-free Queue and Ring Buffer)是计算机科学中的关键概念,尤其是在并发编程和多线程环境下。它们被设计用于在高并发场景下提高数据结构的性能,避免了传统锁机制所带来的性能瓶颈。下面...

    lock-free-wait-free-circularfifo.zip_Free!_circularfifo

    为了实现高效且安全的数据结构,无锁(Lock-Free)和等待自由(Wait-Free)算法应运而生。本篇文章将深入探讨这两种算法在实现先进先出(FIFO)队列中的应用,特别是在多线程环境中的优势和挑战。 首先,我们需要...

    An Optimistic Approach to Lock-Free FIFO Queues

    本文介绍了一种新的动态内存无锁FIFO队列算法,该算法相较于目前最有效且实用的Michael和Scott的无锁FIFO队列(以下简称MS队列)表现更佳。 #### 引言 FIFO队列是支持先进先出语义的并发数据结构,支持enqueue...

    Lock-free Parallel Garbage Collection

    1. **锁自由(Lock-Free)**:在锁自由并发控制中,不存在任何会阻塞其他线程的锁定操作。这意味着即使某个线程由于某种原因被挂起,也不会阻止其他线程继续执行。 2. **并行垃圾回收**:通过利用多处理器的优势,...

    Approximate String Matching和Lock-Free Data Structures

    在IT领域,数据结构是构建高效算法的基础,而“Approximate String Matching”(近似字符串匹配)和“Lock-Free Data Structures”(无锁数据结构)是两个非常关键且具有挑战性的概念。 首先,我们来深入探讨一下...

    一种采用Lock-Free同步机制的数据结构的研究.pdf

    本文提出了一种针对跳表(Skip list)共享数据结构的无锁(Lock-Free)同步机制方法,并对其线性一致性(linear consistency)进行了证明。在嵌入式系统中,混合关键任务的共享优先级调度队列(shared priority ...

    原子指令于Lock-Free数据结构教学笔记

    ### 原子指令与Lock-Free数据结构 #### 原子指令概述 **原子指令**是一种特殊的硬件指令,能够以不可分割的方式对一个或多个内存位置执行操作。这意味着无论其他处理器正在执行何种指令,原子操作要么全部成功,...

    Linux无锁编程终稿.pdf

    所有Wait-free算法都是Lock-free的,但Lock-free并不保证单个线程的饥饿自由。 3. Obstruction-free算法则保证在没有竞争的情况下,一个线程可以在有限步内完成操作。一旦出现竞争,它需要回滚已完成的部分操作。...

    lockfree c#.net

    9. **线程安全的数据结构**:LockFree数据结构如栈、队列、字典等,是并发编程的重要工具,它们在JmBucknall.Structures库中可能都有实现。 10. **并发编程工具与设计模式**:了解如生产者消费者模型、工作窃取等...

    lockfree-shm-ipc.7z

    在"lockfree-shm-ipc"中,开发者可能采用了CAS(Compare and Swap)或FAS(Fetch and Swap)等无锁算法来实现数据的读写操作。 在压缩包中,"lsi.make"和"Makefile"是构建脚本,用于编译和链接项目。"lockfree-shm-...

    lock-free-experiments

    在"lock-free-experiments"这个项目中,我们可以看到实验者通过创建一些基于无锁数据结构的计数器来探索这一概念。这些计数器可能包括自定义实现和使用`AtomicInteger`包装的版本。实验的目标可能是比较它们在不同...

    lock_free_queue.rar

    无锁队列(Lock-Free Queue)是一种在多线程编程中用于提高并发性能的数据结构。在传统的线程安全队列中,通常会使用锁来保护数据的同步,但这种做法可能会导致线程间的竞争条件,进而产生性能瓶颈。无锁队列通过...

    ioking真正无锁的服务器引擎之消息引擎模块(nolock)

    再者,提到“非lock-free”,通常lock-free算法利用硬件支持来实现线程间的同步,以达到无锁效果。但ioking选择了不同的路径,它没有采用传统的lock-free策略,可能是因为lock-free虽然理论上可以避免死锁,但在某些...

    Lock Free tech

    通过上述分析可以看出,Lock Free技术不仅可以应用于具体的算法设计,还可以用于改进现有的多线程编程模式。在实际开发过程中,合理运用Lock Free技术,结合流水线等其他高级并发控制机制,可以大大提升系统的性能和...

Global site tag (gtag.js) - Google Analytics