无锁数据结构(Lock-Free Data Structures)
一个星期前,我写了关于SQL Server里闩锁(Latches)和自旋锁(Spinlocks)的文章。2个同步原语(synchronization primitives)是用来保护SQL Server里的共享数据结构,例如缓存池里的页(通过闩锁(Latches)),锁管理器哈希表里的锁(通过自旋锁(Spinlock))。接下里你会看到越来越多的全新同步原语(synchronization primitives),即所谓的无锁数据结构(Lock-Free Data Structures)。那也是SQL Server 2014里建立内存中OLTP的一个基础,因此在今天的文章里我会给你快速概况介绍下无锁数据结构,还有它们提供了什么。
什么是无锁数据结构(Lock-Free Data Structures)
无锁算法通过非阻塞算法保护共享数据结构。在以前的关于闩锁(Latches)和自旋锁(Spinlock)文章里你已看到,当它们不能获得闩锁或自旋锁时,其他的线程会阻塞。当一个线程等待闩锁,SQL Server把线程放入挂起(SUSPENDED)状态,如果一个线程等待自旋锁,这个线程会在CPU上积极自旋。2个方法都会导致阻塞情形,这就是我们想通过非阻塞算法(Non-Blocking Algorithm)避免的。维基百科对非阻塞算法有个漂亮解释:
“A non-blocking algorithm ensures that threads competing for a shared resource do not have their execution indefinitely postponed by mutual exclusion. A non-blocking algorithm is lock-free if there is guaranteed system-wide progress regardless of scheduling.”
来看下中文字幕:
非阻塞算法保证为共享资源竞争的线程,不会通过互斥让它们的执行无限期暂停。如果有不管调度的系统级进程,非阻塞算法是无锁的。
从这个解释里得出的最重要的结论是一个线程不会被另一个线程阻塞。这是可能的,因为没有传统的锁是用做线程本身同步的。我们来看一个具体的例子:
让我们一步一步来分析这个代码。首先,函数compare_and_swap的实现是通过一个直接在CPU级别上的原子硬件指令(atomic hardware instruction)——CMPXCHG来实现。我想演示下在CMPXCHG里实现什么样的逻辑:你比较值与一个期望值,如果它们一样的话,老的值会赋予新的值。因为CHPXCHG的整个逻辑是在CPU本身上作为一个原子单元实现的,没有其他线程可以中断这个汇编运算码的执行。
为了存储自旋锁本身的状态,名为lock的变量被使用。因此线程在整个循环里自旋转,直到自旋转锁同步变量被解锁。如果这个发生的话,线程可以锁住同步变量,最后会进入在线程安全方式的临界区(critical section)。这又是自旋锁的简单演示(非线程安全)——事实上事情比这个难,且复杂很多。
这个传统方法的最大问题是,在线程同步里涉及到共享资源:自旋转锁同步变量lock。如果一个线程把持自旋锁,且挂起了,当其他线程尝试获取自旋锁就会卡在当型循环里。你可以通过引入无锁代码技术避免这个问题。
如你所见,Foo方法的实现已经完全改变了。不是尝试去获得自旋锁,实现方法在原子加进行前,只是检查是否有其它线程修改共享变量(原先是通过自旋锁受保护)。这就是说没有用到了共享资源,线程之间也不会彼此阻塞。这就是无锁数据结构(Lock-Free Data Structures)和非阻塞算法(Non-Blocking Algorithm)的主要思路。
在SQL Server 2014里的内存中OLTP也使用同样的方法来构建BW-TREE映射表的页改变。因此就不会涉及到锁,闩锁和自旋锁。如果内存中OLTP看到在映射表里的页地址以in个改变,这就是说另一个线程已经开始在那页上的修改——但还未完成(在CPU上同时有其它线程被调度)。在内存中OLTP里各个线程是相互合作来工作。因此如果线程看到映射表里的修改,就完成这个”挂起“操作是可能的——例如页分裂。
一个内存中OLTP的页分裂包含多个原子操作。因此一个线程可以开始一个页分裂,另一个线程可以最后完成这个页分裂。在以后的文章里我会讨论这些页分裂的更多信息,实现BW-TREE里改变,让这个复杂方法成为可能。
小结
在今天的文章里我向你介绍了无锁数据结构背后的主要思路。这个主要思路是在线程本身尝试执行一个原子操作前,检查是否有其它线程完成一个操作。因此不需要通过像自旋锁的同步原语来保护临界区。自SQL Server 2014起,无锁数据结构和非阻塞算法的思路已被内存中的OLTP使用。
感谢关注!
参考文章:
https://www.sqlpassion.at/archive/2014/09/29/lock-free-data-structures/
无锁数据结构(Lock-Free Data Structures)的更多相关文章
- 泛函编程(5)-数据结构(Functional Data Structures)
编程即是编制对数据进行运算的过程.特殊的运算必须用特定的数据结构来支持有效运算.如果没有数据结构的支持,我们就只能为每条数据申明一个内存地址了,然后使用这些地址来操作这些数据,也就是我们熟悉的申明变量 ...
- C++ 无锁数据结构
https://www.zhihu.com/question/52629893/answer/131731126
- 理解 Memory barrier(内存屏障)无锁环形队列
原文:https://www.cnblogs.com/my_life/articles/5220172.html Memory barrier 简介 程序在运行时内存实际的访问顺序和程序代码编写的访问 ...
- 使用C++11实现无锁stack(lock-free stack)
前几篇文章,我们讨论了如何使用mutex保护数据及使用使用condition variable在多线程中进行同步.然而,使用mutex将会导致一下问题: 等待互斥锁会消耗宝贵的时间 — 有时候是很多时 ...
- boost 无锁队列
一哥们翻译的boost的无锁队列的官方文档 原文地址:http://blog.csdn.net/great3779/article/details/8765103 Boost_1_53_0终于迎来了久 ...
- 并发编程(三): 使用C++11实现无锁stack(lock-free stack)
前几篇文章,我们讨论了如何使用mutex保护数据及使用使用condition variable在多线程中进行同步.然而,使用mutex将会导致一下问题: 等待互斥锁会消耗宝贵的时间 - 有时候是很多时 ...
- 并发编程入门(三): 使用C++11实现无锁stack(lock-free stack)
前几篇文章,我们讨论了如何使用mutex保护数据及使用使用condition variable在多线程中进行同步.然而,使用mutex将会导致一下问题: 等待互斥锁会消耗宝贵的时间 - 有时候是很多时 ...
- 【DPDK】【ring】从DPDK的ring来看无锁队列的实现
[前言] 队列是众多数据结构中最常见的一种之一.曾经有人和我说过这么一句话,叫做“程序等于数据结构+算法”.因此在设计模块.写代码时,队列常常作为一个很常见的结构出现在模块设计中.DPDK不仅是一个加 ...
- 无锁同步-JAVA之Volatile、Atomic和CAS
1.概要 本文是无锁同步系列文章的第二篇,主要探讨JAVA中的原子操作,以及如何进行无锁同步. 关于JAVA中的原子操作,我们很容易想到的是Volatile变量.java.util.concurren ...
随机推荐
- java.lang.ClassNotFoundException: org.junit.Assume$AssumptionViolatedException
java.lang.ClassNotFoundException: org.junit.Assume$AssumptionViolatedException 在spring框架中进行单元测试,出现标题 ...
- PoolMon 使用
PoolMon 显示 PoolMon 在命令窗口中显示有关池内存分配的数据列.使用箭头键.PAGE UP 和 PAGE DOWN 键在数据间滚动. 注意 若要查看全部 PoolMon 显示,则 ...
- iis 故障导致网站无法访问
服务器使用两三个月突然,昨天无法访问,重启后正常,第二次发生这样的事情了,打开 C:\WINDOWS\system32\LogFiles\HTTPERR 下的 httperr1.txt 201 ...
- 64位Windows无法打开会声会影X5的解决方法
低版本和破解版都不好用了. 由于微软更新补丁而引起的会声会影停止工作的问题,建议大家卸载补丁[KB3126587]和[KB3126593][KB2140410 ]解决或者(修复包)修复,更换高版本使用 ...
- 【Vegas原创】RHEL6多界面切换方法
CTRL+ALT+Fn(n=1-6) F1,是图形化界面 F2-F6,是字符型界面. 每个界面可以干不同的事情,很牛叉.
- Codeforces Round #271 (Div. 2)题解【ABCDEF】
Codeforces Round #271 (Div. 2) A - Keyboard 题意 给你一个字符串,问你这个字符串在键盘的位置往左边挪一位,或者往右边挪一位字符,这个字符串是什么样子 题解 ...
- Mac工具
iterm2是一个替代终端和iTerm的后继项目.它支持 OS 10.5 或者更新版本.iterm2 提供更多你需要的功能和特点. Flashlight,快速且全面地显示所有「关键词」索引出的结果 参 ...
- 初探Stage3D(二) 了解AGAL
关于本文 本文并无打算事无巨细的介绍一遍AGAL,仅仅是对现有文档的一些理解及汇总,所以请先阅读相参考文档 AGAL概念 参考资料 http://www.adobe.com/devnet/flashp ...
- 精选29款非常实用的jQuery应用插件
今天我们来分享一些实用的jQuery应用插件,没有特别花哨,但都比较实用,jQuery菜单.jQuery图片都有涉及到,一起来看看. 1.jQuery+CSS3仿IOS无线局域网Wifi DEMO演示 ...
- [转]C++学习–基础篇(书籍推荐及分享)
C++入门 语言技巧,性能优化 底层硬货 STL Boost 设计模式 算法篇 算起来,用C++已经有七八年时间,也有点可以分享的东西: 以下推荐的书籍大多有电子版.对于技术类书籍,电子版并不会带来一 ...