Data Race Free 是多线程程序是非常重要的概念,因为Java 和 C++的内存模型都是基于 Data Race Free 的,这篇文章将介绍这个概念的由来,另一篇文章《对Data Race Free的理解》介绍它的主要思想。

事情要追溯到遥远的1979年, Lamport 在他的著名论文 How to make a multiprocessor computer that correctly executes multiprocess programs 中提出了今后在内存模型领域被广泛使用的概念 :sequential consistency,即顺序一致性。这篇文章告诉我们,你要做一台多处理器的计算机,需要满足什么条件,才能保证程序的正确性。当然,这里的程序跑在不同处理器上,共享同一块内存。虽然现在不说多处理器了,都说多核,多线程,但是问题的本质是没有变的。就是多个执行单元一起完成一个任务,并且通过共享存储单元的方式通信,在这种情况下,底层的系统需要提供什么样的支持,才能保证计算的结果和程序员的预期是一样的。

7年后的1986年,Dubois, Scheurich , Briggs 三人在论文 Memory access buffering in multiprocessors 中对 Lamport 的工作进行了扩展,他们提出了一种框架,用于分析共享内存的多处理器系统中的一致性问题。文中引入了三个 states,以此为基础提出了strong ordering的概念,并说明了他与Lamport提出的sequential consistency是一致的。但是,strong ordering对内存操作的限制太强了,对系统性能是一个阻碍,所以,他们又提出了 weak ordering的概念,以此提高系统性能。 满足weak ordering的系统并不是 sequential consistency的,程序员们需要自己去声明同步变量,以保证程序的正确性。

又过了4年,到了1990年,Adve大妈出手了,大妈现在是内存模型这个领域的权威,Java和C++内存模型的确立都有大妈的功劳,而Java和C++内存模型中相当重要的Data Race Free 概念就是Adve大妈在这一年提出的。

在这篇名为 Weak ordering—a new definition的文章中,Adve对Dubois等人提出的Weak Ordering进行了新的定义,并做出了一些修改以便进一步提高系统的性能。 新的定义出于这样一种想法,程序员习惯使用 sequential consistency来推断程序的运行结果,而底层的系统要想取得更高的性能,又不能使用sequential consistency内存模型来运行程序。那么

如何使得程序员可以使用sequential consistency推断程序结果,底层的实现又可以进行种种优化呢?

解决方案是:对程序本身进行足够的同步。

这种内存模型保证:如果你的程序进行了足够的同步,那么在我的weak oerding内存模型上运行,我可以保证结果和你在sequential consistency模型下运行的结果一样。

这样一来,程序员保证程序正确同步,就可以使用sequential consistency推断程序结果,而底层又可以灵活地进行各种优化,提高系统性能。

这里有一个关键问题:

什么叫“足够的同步”

Adve提出了Data Race Free的概念,也就是说,你的程序要是满足Data Race Free的条件了,你的同步就足够了,“足够”的意思就是说,这程序在weak ordering上跑和在sequential consistency上跑,结果是一样一样的~

Adve对weak ordering给出的新定义是:

Hardware is weakly ordered with respect to a synchronization model if and only if it appears sequentially consistent to all software that obey the synchronization model.

这里的synchronization model的一种实现方式,就是 Data Race Free。

Data Race Free 后来成为了 Java 和 C++ 内存模型的基础。

Java 的内存模型最早出现在1995年,但是自1997年起,这一内存模型被发现了许多严重的错误和缺陷,它阻碍了很多优化措施,对程序的安全性也没有足够的保证。2001年JSR 133被确立下来,由William Pugh领导,专家组的成员包括了Adve,Doug Lea, William Pugh等。2004年,JSR 133最终版本发布。2005年,Manson Jeremy, William Pugh, 和 Sarita V. Adve 一同发表了论文 The Java memory model,描述了最新的Java内存模型,这一内存模型在Java 5.0中引入,一直沿用至今。

Java 内存模型的关键是:如果多线程程序满足Data Race Free,那么内存模型保证程序执行结果和sequentially consistent模型下一样。另外,Java 内存模型的复杂之处还在于,为了保证程序的安全性,即使多线程程序不满足Data Race Free,我们也要对它进行一定程度的限制,这种限制必须恰到好处,太强会阻碍合理的优化,太弱保证不了程序的安全性。

三年后的2008年,Hans-J. Boehm 和 Sarita V. Adve 一同发表了文章 Foundations of the C++ concurrency memory model,描述了C++内存模型的基础,这一内存模型为C++ 11标准中的线程提供了明确的语义。

C++内存模型与的关键在于:如果多线程程序满足Data Race Free,那么内存模型保证程序执行结果和sequentially consistent模型下一样。与Java内存模型不同,对于那些不满足 Data Race Free的多线程程序,C++内存模型不对其结果提供任何保证。另外,C++内存模型提供了一些特性用以实现不同的内存模型。

Data Race Free 的前世今生相关推荐

  1. 数据竞争(data race)问题分析的利器——valgrind的Helgrind

    数据竞争(data race)是指在非线程安全的情况下,多线程对同一个地址空间进行写操作.一般来说,我们都会通过线程同步方法来保证数据的安全,比如采用互斥量或者读写锁.但是由于某些笔误或者设计的缺陷, ...

  2. golang-exec cmd data race

    问题背景:bytes.Buffer grow panic panic: runtime error: slice bounds out of range [:1024] with capacity 5 ...

  3. 数据争用(data race) 和竞态条件(race condition)

    在有关多线程编程的话题中,数据争用(data race) 和竞态条件(race condition)是两个经常被提及的名词,它们两个有着相似的名字,也是我们在并行编程中极力避免出现的.但在处理实际问题 ...

  4. golang的 data race 分析

    golang的data race 一.名词解析 1.data race: Any race is a bug 定义: ①多个线程(协程)对于同一个变量.②同时地.③进行读/写操作.并且④至少有一个线程 ...

  5. golang data race 竞态条件

    golang race condition 竞态条件 data race race condition golang race detector golang的协程机制使得编写并发代码变得非常容易,但 ...

  6. go 并发编程 之 数据竞争 data race (三)

    前言 两个或多个 goroutine 访问同一个资源(如变量或数据结构),并尝试对该资源进行读写而不考虑其他 goroutine.这种类型的代码可以创建你见过的最疯狂和最随机的 bug.通常需要大量的 ...

  7. golang 记一次data race排查过程

    golang 记一次data race排查过程 背景 data race 现场 解决思路 经验总结 data race在写并发代码时候经常遇到,相关基础概念的介绍可以参考之前一篇文章:golang d ...

  8. 别混淆数据争用(data race) 和竞态条件(race condition)

    在有关多线程编程的话题中,数据争用(data race) 和竞态条件(race condition)是两个经常被提及的名词,它们两个有着相似的名字,也是我们在并行编程中极力避免出现的.但在处理实际问题 ...

  9. go语言踩坑:data race导致的输出结果与预期结果不一致

    一.第一个例子 package mainimport ("fmt""sync""time" )type person struct {Nam ...

最新文章

  1. 最新android webview,Android 关于WebView全方面的使用(项目应用篇)
  2. RabbitMQ应对不同阶段丢失消息的处理方案
  3. . SQL多条件查询存储过程
  4. 不会配置HTTPS?给我5分钟,手把手教你
  5. python 使用 ipx协议_肝了三天,万字长文教你玩转 tcpdump,从此抓包不用愁
  6. js系列:时间格式转成时间戳和比较某个时段是否在另一个时间段内
  7. 计算流体力学CFD入门教程介绍
  8. Bootstrap3 标题样式
  9. 听说你的淘客群又做死了?来学学群维护这几招!
  10. 【云原生|实战研发】2:Pod的深入实践与理解
  11. linux博通bcm4313无线网卡,在Deepin 15.7系统中解决BCM4313无线网卡网速慢的问题
  12. CSS中flex的用法( 学习笔记 )
  13. P1551 亲戚 并查集
  14. 飞凌嵌入式AM62x核心板,赋能新一代HMI
  15. emoji语言常用图标收集(有趣的emoji)
  16. 如何仅使用SaaS开发软件
  17. RSocket 与 gRPC性能对比
  18. block-insecure-private-network-requests没有怎么解决
  19. python中的缩进快捷键_python如何缩进
  20. 暗夜精灵怎么重装系统?

热门文章

  1. java多客户端聊天程序,java – 多客户端聊天程序,向所有客户端广播聊天?
  2. 数据库查询尚未归还的借书记录(查询借书但未归还的读者的编号、姓名及所借图书编号、
  3. Win8环境下USB Blaster驱动安装问题解决方法
  4. pyecharts系列之Bar的用法
  5. kylin搭建及使用
  6. 对比学习系列(二)---MoCo 系列
  7. 【JavaScript】最简单的一个例子
  8. Silverlight正式发布 六间房:得看微软有无决心
  9. Spring Cloud Stream中文指导手册
  10. DOL HDR 先长后短曝光的原因猜测