查了下MSDN的解释:

MemoryBarrier is required only on multiprocessor systems with weak memory ordering (for example, a system employing multiple Intel Itanium processors).

Synchronizes memory access as follows: The processor executing the current thread cannot reorder instructions in such a way that memory accesses prior to the call to MemoryBarrier execute after memory accesses that follow the call to MemoryBarrier.

就是说多核处理器会对运行CPU指令顺序重排优化,MemoryBarrier可以阻止指令重排,调用Thread.MemoryBarrier()之后的代码中内存访问不能再这之前就完成了。也就是它可以限制指令重排和内存读写的缓存。

下面有段代码,在release编译情况下会死循环(debug应该是没做instructions reorder而不会有问题)

            bool complete = false;
            var t = new Thread(() =>
            {
                bool toggle = false;
                while (!complete)
                    toggle = !toggle;
            });
            t.Start();
            Thread.Sleep(1000);
            complete = true;
            t.Join();

问题原因:

1.编译器、CLR或者CPU可能重新排序了程序指令,以此提高效率。

2.编译器、CLR或者CPU引入缓存优化导致其他的线程不能马上看到变量值的更改。

尝试了下将Thread.MomoryBarrier加到while中,保证complete读到的最新的:

此例子中MomoryBarrier 应该时解决jit时过度优化,虽然两个核心cache line 不会及时同步,complete 值修改通过MSIE协议也很快的通知到其他核心。

出现死循环在于jit 任魏complete值一直是false,并没有执行load操作,而是直接判断true跳转。

            bool complete = false;
            var t = new Thread(() =>
            {
                bool toggle = false;
                while (!complete)
                {
                   Thread.MemoryBarrier();
                    toggle = !toggle;
                }
            });
            t.Start();
            Thread.Sleep(1000);
            complete = true;
            t.Join();

在看一个例子:(来自《window 并发编程指南》内存模型部分)MyObject mo= ..;int f= mo.field;if(f==0){  //same operation  Console.WriteLine(f);}如果mo.field 在读取和Console.WriteLine相隔足够远,那么编译器可能会认为读mo.field 读取两遍会更有效,被编译成如下代码:
MyObject mo= ..;if(mo.filed==0){  //same operation  Console.WriteLine(mo.field);}
编译器可能判断,保留这个值是否给寄存器带来压力并导致栈空间的低效使用,并且之个分支是否很少被使用(因此f值就不需要多次)这样带来多线程问题,将f值使用volatitle修饰,可禁止这种优化

转载于:https://www.cnblogs.com/lulu/archive/2012/05/26/2519580.html

MemoryBarrier方法相关推荐

  1. 第二节:深入剖析Thread的五大方法、数据槽、内存栅栏

    一. Thread及其五大方法 Thread是.Net最早的多线程处理方式,它出现在.Net1.0时代,虽然现在已逐渐被微软所抛弃,微软强烈推荐使用Task(后面章节介绍),但从多线程完整性的角度上来 ...

  2. 【转】1.3异步编程:线程同步基元对象

    开始<异步编程:同步基元对象(上)> 示例:异步编程:线程同步基元对象.rar 如今的应用程序越来越复杂,我们常常需要多线程技术来提高我们应用程序的响应速度.每个线程都由自己的线程ID,当 ...

  3. 在 Oracle Enterprise Linux 和 iSCSI 上构建您自己的 Oracle RAC 11g 集群

    作者:Jeffrey Hunter 了解如何以低于 2,700 美元的费用在 Oracle Enterprise Linux 上安装并配置 Oracle RAC 11g 第 2 版开发集群. 本指南中 ...

  4. Java面试题大全2021版

    一.Java 基础 JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境. JRE:Java Run ...

  5. 【转】细说.NET中的多线程 (六 使用MemoryBarrier,Volatile进行同步)

    上一节介绍了使用信号量进行同步,本节主要介绍一些非阻塞同步的方法.本节主要介绍MemoryBarrier,volatile,Interlocked. MemoryBarriers 本文简单的介绍一下这 ...

  6. Lock,LockFree,MemoryBarrier,ConcurrentCollection

    最近看并行编程书本的一些心得,简单记录下多线程和并行编程必知必会的几个概念,再次加深自己的理解. .NET Framework4提供了一个新的命名空间System.Collections.Concur ...

  7. Kotlin协程使用,协程使用注意事项,协程中的await方法使用|不使用suspend使用协程

    参见 码云 协程使用方法一 (Dispatchers调度器模式) 指定不同线程.同线程会挂起并阻塞(挂起是不影响主线程执行,阻塞是同样的IO线程会阻塞) withContext(Dispatchers ...

  8. IDEA中将代码块封装为方法,IDEA代码重构快捷键

    IDEA中将代码块封装为方法 选中要转换的代码块,快捷键: Windows快捷键:Alt + Shift + M Mac快捷键:Alt + Command + M 如图:

  9. IDEA自动生成对象所有set方法

    idea中有一款插件能够生成对象所有的set方法,GenerateAllSetter :下载地址 步骤1:将下载好的压缩包放在自己记得的文件夹中,在idea中进行导入 步骤2:在本地选中刚才的压缩包, ...

  10. List元素互换,List元素转换下标,Java Collections.swap()方法实例解析

    Java Collections.swap()方法解析 jdk源码: public static void swap(List<?> list, int i, int j) {// ins ...

最新文章

  1. 400全集python全套视频教程-千锋出品全套python视频教程,400大全集,你了解吗?...
  2. python 斐波拉契递归 尾递归 备忘录 动态规划 迭代
  3. tensorflow环境下的识别食物_研究室秒变后厨,TensorFlow被馋哭!日本团队用深度学习识别炸鸡,救急便当工厂...
  4. mfc通过信号量保证线程同步
  5. JSON数据、字符串拼接、宽字符处理、数组、Notice警告、isset和empty、变量、作用域、常量、include和require
  6. 多容器,Nginx容器灵活切换PHP版本!同时运行多个PHP容器
  7. 【javascript】 的严格模式 详解
  8. cad中计算机的快捷键,CAD常用快捷键汇总
  9. android手机控制电视,类Siri语音控制技术 Android手机也能控制电视
  10. 火热的区块链技术,也能解决文化领域的这些痛点
  11. android旅游视频播放,VPlayer视频播放器
  12. 程序员到底有没有必要买一台阿里云服务器?
  13. Oracle 基本SQL语句
  14. hibernate配置映射的问题
  15. 11台计算机的英语,世界第一台计算机英文缩写名为
  16. C语言--数据在内存中的存储
  17. 聊城市普通话水平测试软件音频,聊城市普通话水平测试培训-聊城市教师教育网.ppt...
  18. cf服务器无响应,穿越火线优化玩家分辨率,告别白屏未响应!
  19. MATLAB中cla函数
  20. 六.实战——Excel表格的导入和导出

热门文章

  1. Matlab——数组
  2. 给大家讲解一下 AIDL原理分析
  3. 向量积的二维物理意义,二维向量叉乘几何意义
  4. Python实现Mean Shift算法
  5. 软件测试中的可用性、可维护性、可靠性有什么区别?
  6. MapGISnbsp;K9nbsp;SP3amp;nb…
  7. Java-Spark系列6-Spark SQL编程实战
  8. linux通过80端口系统入侵,【转】21和80端口的入侵
  9. VLAN Trunk
  10. 显示农历天气时钟小部件下载_软媒时间-时间栏的效率小软件