对 Data Race Free 的理解

Data Race Free 的动机

Data Race Free 是对多线程程序 同步程度 的一种描述,假如你的多线程程序的同步程度满足 DRF 的要求,那么,你的程序会有这样一个好处:

程序在弱一致性模型下执行,执行的结果与在SC模型下执行一样

这意味着,程序员在写程序时,可以按SC模型来推断程序的执行。而程序在底层运行时,可以享受弱一致性模型带来的种种优化措施。

Data
Race Free 具体内容

DRF 要求多线程程序中不能有冲突的操作。

什么是冲突的操作呢?

冲突的操作是指:两个操作来自不同线程,操作同一地址,至少有一个是写操作。

如何让冲突的操作不冲突呢?

需要使用同步操作将冲突的操作隔离开。

为什么要用同步操作将冲突的操作隔离开呢?

因为如果不隔离开,程序在弱一致性模型下执行的结果就和在SC模型下执行的结果不一样了。这意味着如果你用SC模型推断程序执行结果,而程序又运行在弱一致性模型下,那么程序的真正结果可能和你推断的不一样。

那么,又为什么:如果不隔离开,程序在弱一致性模型下执行结果就和SC模型下不一样了呢?

这个问题其实在问:为什么隔离会使得程序在弱一致性模型下执行结果与SC模型下执行结果一致?

这个问题用一句话来回答是:隔离使得我们可以找到所有操作的一种全序,而这种全序正是SC所需要的。

同步操作将相互冲突的操作隔离开,这种隔离为原本无序的多线程程序添加了一些顺序:

  • 同步操作之间有顺序了
  • 同步操作与其之前的所有操作之间有顺序了
  • 同步操作与其之后的所有操作之间有顺序了

这些顺序保证了程序在弱一致性模型下与在SC模型下执行结果一样。

另外,我们还发现,有些操作之间并没有顺序保证,这正是DRF的优势所在,这些无须顺序保证的操作可以在弱一致性模型下得到优化,同时他们的无序又不会使得执行结果与SC下有任何不同。

如果我们想找一个所有操作之间的全序,只需要在这些无须保证顺序的操作中随便选择一个顺序,另外,还需要保证那些因为同步而添加的顺序关系。如此构成一个全序。这个全序正是SC模型所需要的。

由此,我们也明白了DRF的精髓:

只保证必要的顺序,不保证不必要的顺序。

所谓必要是指,保证这些顺序就可以使得程序在弱一致性模型下的执行结果与SC模型下的执行结果一致,不保证就不行。

对 Data Race Free 的理解,布布扣,bubuko.com

时间: 2024-08-07 03:10:34

对 Data Race Free 的理解的相关文章

Data Race Free 的前世今生

Data Race Free 是多线程程序是非常重要的概念,因为Java 和 C++的内存模型都是基于 Data Race Free 的,这篇文章将介绍这个概念的由来,另一篇文章<对Data Race Free的理解>介绍它的主要思想. 事情要追溯到遥远的1979年, Lamport 在他的著名论文 How to make a multiprocessor computer that correctly executes multiprocess programs 中提出了今后在内存模型领域被

Golang Data Race Detector

原文链接:http://maoqide.live/post/golang/golang-data-race-detector/ [译] https://golang.google.cn/doc/articles/race_detector.html golang 中的几种 Data Race 场景及 Data Race 检测工具. Introduction 数据竞争是并发系统中最常见和最难 debug 的 bug 类型之一,当两个 goroutine 同时访问同一个变量并且至少有一个是写入时,就

[数据库事务与锁]详解七: 深入理解乐观锁与悲观锁

注明: 本文转载自http://www.hollischuang.com/archives/934 在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段. 无论是悲观锁还是乐观锁,都是人们定义出来的概念,可以认为是一种思想.其实不仅仅是关系型数据库系统中有乐观锁和悲观锁的概念,像memcache.hibernate.

对 Java 内存模型的理解

Java 内存模型 Java内存模型规定了在多线程程序中,什么样的行为是允许出现的,什么样的行为是禁止出现的.这样说可能有点抽象,我们换一个角度.将程序行为抽象成读操作和写操作,每个线程有自己的局部变量,同时线程之间还存在共享变量.那么一个多线程程序执行结束后,所有变量会有一个最终值.Java内存模型来决定什么样的值合法,什么样的值不合法. 内存模型不能要求的太严格,这样会阻碍很多优化方法,降低程序执行的效率,但也不能要求的太松,因为这样会导致一些执行结果违反我们的直觉.例如指令间的重排序问题,

happens-before通俗理解

学习Java并发,到后面总会接触到happens-before偏序关系.初接触玩意儿简直就是不知所云,下面是经过一段时间折腾后个人对此的一点浅薄理解,希望对初接触的人有帮助.如有不正确之处,欢迎指正. synchronized.大部分锁,众所周知的一个功能就是使多个线程互斥/串行的(共享锁允许多个线程同时访问,如读锁)访问临界区,但他们的第二个功能 —— 保证变量的可见性 —— 常被遗忘. 为什么存在可见性问题?简单介绍下.相对于内存,CPU的速度是极高的,如果CPU需要存取数据时都直接与内存打

深入理解乐观锁与悲观锁

在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段. 无论是悲观锁还是乐观锁,都是人们定义出来的概念,可以认为是一种思想.其实不仅仅是数据库系统中有乐观锁和悲观锁的概念,像memcache.hibernate.tair等都有类似的概念. 针对于不同的业务场景,应该选用不同的并发控制方式.所以,不要把乐观并发控制和悲

深入理解Java 8 Lambda(类库篇——Streams API,Collectors和并行)

转:http://zh.lucida.me/blog/java-8-lambdas-inside-out-library-features/ 关于 深入理解 Java 8 Lambda(语言篇--lambda,方法引用,目标类型和默认方法) 深入理解 Java 8 Lambda(类库篇--Streams API,Collector 和并行) 深入理解 Java 8 Lambda(原理篇--Java 编译器如何处理 lambda) 本文是深入理解 Java 8 Lambda 系列的第二篇,主要介绍

[转]深入理解Java 8 Lambda(类库篇——Streams API,Collectors和并行)

以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-library-features 本文谢绝转载,如需转载需征得作者本人同意,谢谢. -------------------------------------内容分割线--------------------------------------------------------- 深入理解Java

【转】深入理解乐观锁与悲观锁

在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段. 无论是悲观锁还是乐观锁,都是人们定义出来的概念,可以认为是一种思想.其实不仅仅是关系型数据库系统中有乐观锁和悲观锁的概念,像memcache.hibernate.tair等都有类似的概念. 针对于不同的业务场景,应该选用不同的并发控制方式.所以,不要把乐观并发控