Mutex和内存可见性
http://ifeve.com/mutex-and-memory-visibility/
POSIX内存可见性规则
IEEE 1003.1-2008定义了XBD 4.11内存同步中的内存可见性规则。特别地,POSIX实现保证:
pthread_create()
同步:任何变量在pthread_create()
调用之前修改,对刚由它创建的线程来说是可见的。当变量在pthread_create()
之后修改,那么这条规则就不能保证了,即使是在线程开始执行之前修改的。pthread_join()
同步:任何变量由某线程在结束之前修改,那回收(join)它的另一线程 在pthread_join()
完成后是可见的。- mutex操作——
pthread_lock(), pthread_timedlock(), pthread_trylock() , pthread_unlock()
同步:任何变量由线程对mutex解锁之前修改,对后面成功锁住同一mutex的线程是可见的,请参阅图2。再强调一次,如果锁住另一个mutex,或者根本没有加锁,又或者变量在pthread_unlock之后又被修改的,这一规则不保证。
总结
读完本文后,你应该弄明白Cert POS03-C编码规则背后的原因:
POS03-C:请勿使用volatile作为同步原语
只要遵从POSIX的内存可见性规则这条底线,编写出来的代码理所当然是安全的。特别当一个线程写某个值,而另一线程读此值时,即使能保证原子访问,仍需要使用mutex来构造适当的内存同步访问。
Posix 内存可见性:
1 当线程调用pthread_create时,它所能看到的内存值也是它建立的线程能够看到的。任何在调用pthread_create之后向内存写入的数据,可能不会被建立的线程看到,即使写操作发生在启动新线程之前。
2 当线程解锁互斥量时看到的内存中的数据,同样也能被后来直接锁住(或通过等待条件变量锁住)相同互斥量的线程看到。同样,在解锁互斥量之后写入的数据不必被其他线程看见,即使写操作发生在其他线程锁互斥量之前。
3 线程终止(或者通过取消操作,或者从启动函数中返回,或者调用pthread_exit)时看到的内存数据,同样能够被连接该线程的其他线程(通过调用pthread_join)看到。当然,终止后写入的数据不会被连接线程看到,即使写操作发生在连接之前。
4 线程发信号或广播条件变量时看到的内存数据,同样可以被唤醒的其他线程看到。而在发信号或广播之后写入的数据不会被唤醒的线程看到,即使写操作发生在线程被唤醒之前。
在实际应用的使用方法:
首先,确保哪些可能的地方只有一个线程能访问某段数据。线程的寄存器变量不能被其他线程修改。线程分配的堆栈和堆空间是私有的,除非线程将指向该内存的指针传给其他线程。任何放在register或auto变量中的数据可以在随后的某时刻读取,就像在完全同步的程序中一样。在线程间共享的数据越少,需要做的工作越多。
其次,任何时候两个线程需要访问相同数据时,你就需要应用其中一条内存可视化规则,大多数情况下是指使用互斥量,这不仅是为了保护多个写操作,即使线程是读数据,它也需要锁住互斥量以确保读到最新的数据值。
有一些特别的情况下不需要使用互斥量来确保可视性。如果线程设置了一个全局变量,然后创建了一个新线程读取同一个变量,则新线程将看不到旧的变量值(只能看到改过的新的变量值)。但是,若你创建了一个新线程然后再设置变量的值,则新线程可能看不到新的变量值,即使原线程在新线程读取数据之前向变量内写入了新值。
Mutex和内存可见性的更多相关文章
- java并发编程(十四)同步问题的内存可见性
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17288243 加锁(synchronized同步)的功能不仅仅局限于互斥行为,同时还存在另 ...
- 一篇讲Java指令重排和内存可见性的好文
在这里: http://tech.meituan.com/java-memory-reordering.html 指令重排和内存可见性(缓存不一致)是两个不同的问题. volatile关键字太强,即阻 ...
- 一个Java内存可见性问题的分析
如果熟悉Java并发编程的话,应该知道在多线程共享变量的情况下,存在“内存可见性问题”: 在一个线程中对某个变量进行赋值,然后在另外一个线程中读取该变量的值,读取到的可能仍然是以前的值: 这里并非说的 ...
- 1 Java线程的内存可见性
Java内存的可见性 可见性: 一个线程对共享变量的修改,能够及时被其它线程看到 共享变量: 如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量 Java内存模型(JM ...
- JVM并发机制的探讨——内存模型、内存可见性和指令重排序
并发本来就是个有意思的问题,尤其是现在又流行这么一句话:“高帅富加机器,穷矮搓搞优化”. 从这句话可以看到,无论是高帅富还是穷矮搓都需要深入理解并发编程,高帅富加多了机器,需要协调多台机器或者多个CP ...
- 细说Java多线程之内存可见性
编程这些实践的知识技能,每一次学习使用可能都会有新的认识 一.细说Java多线程之内存可见性(数据挣用) 1.共享变量在线程间的可见性 共享变量:如果一个 ...
- 《Java 并发编程实战》读书笔记之二:图文讲述同步的另一个重要功能:内存可见性
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17288243 加锁(synchronized同步)的功能不仅仅局限于互斥行为,同时还存在另 ...
- God 1.1.1 多线程之内存可见性
共享变量在线程间的可见性 synchronize实现可见性 volatile实现可见性 指令重排序 as-if-serial语义 volatile使用注意事项 synchronized和volatil ...
- 转: 【Java并发编程】之十四:图文讲述同步的另一个重要功能:内存可见性
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17288243 加锁(synchronized同步)的功能不仅仅局限于互斥行为,同时还存在另 ...
随机推荐
- C语言 文件操作4--文件结构体FILE的理解以及缓冲区再讲
//文件结构体FILE的理解以及缓冲区再讲 #include<stdio.h> #include<stdlib.h> //要点:文件结构 //struct _iobuf { / ...
- U3D physics总结
物理系统基于collider, 没有collider的物体不会发生任何主动和被动的物理交互,也不会产生trigger相关消息. 当且仅当A和B都有碰撞体时,两者才有可能发生交互,才有可能产生trigg ...
- C# winform 上传文件到服务器
1.首先要在服务器端新建一个网站axpx页 然后再网站的后台写代码获取winform传过来的文件名. 声明:这个方法虽然最简单最省事,但是上传大文件可能会报错,我的机器是10M, 超过10M就会提示报 ...
- 快钱支付与Sql Server的乐观锁和悲观锁
在实际的多用户并发访问的生产环境里边,我们经常要尽可能的保持数据的一致性.而其中最典型的例子就是我们从表里边读取数据,检查验证后对数据进行修改,然后写回到数据库中.在读取和写入的过程中,如果在多用户并 ...
- [CareerCup] 5.1 Insert Bits 插入位
5.1 You are given two 32-bit numbers, N and M, and two bit positions, land j. Write a method to inse ...
- [CareerCup] 11.1 Merge Arrays 合并数组
11.1 You are given two sorted arrays, A and B, where A has a large enough buffer at the end to hold ...
- iOS——百度统计
百度移动统计(http://mtj.baidu.com)是一款专业的移动应用统计分析工具,支持ios和android平台.开发者可以方便地通过嵌入统计SDK,对移动应用进行全方位监测,实时监控产品表现 ...
- iOS 苹果自带地图定位Core Location
Core Location是iOS SDK中一个提供设备位置的框架.可以使用三种技术来获取位置:GPS.蜂窝或WiFi.在这些技术中,GPS最为精准,如果有GPS硬件,Core Location将优先 ...
- 20145222黄亚奇《Java程序设计》第7周学习总结
教材学习内容总结 第十三章 时间与日期 即使标注为GMT(格林威治时间),实际上谈到的的是UTC(Unix时间)时间. 秒的单位定义时基于TAI.也就是铯原子辐射的振动次数. Unix时间是1970年 ...
- 学习笔记——Maven实战(八)常用Maven插件介绍(下)
我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven- compiler-plugin完成的.进一步说,每个任务对应 ...