栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

为什么我们需要Thread.MemoryBarrier()?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

为什么我们需要Thread.MemoryBarrier()?

您将很难重现此错误。实际上,我什至会说您将永远无法使用.NET
framework来重现它。原因是因为Microsoft的实现使用强大的内存模型进行写操作。这意味着将写入视为易失性。易失性写入具有锁定释放语义,这意味着必须在当前写入之前提交所有先前的写入。

但是,ECMA规范具有较弱的内存模型。因此,从理论上讲,Mono或什至是.NET framework的将来版本都有可能开始表现出越野车行为。

因此,我要说的是,消除障碍#1和#2几乎不会对程序的行为产生任何影响。当然,这不是保证,而是仅基于当前CLR实施的观察结果。

消除3号和4号障碍肯定会产生影响。这实际上很容易复制。好吧,本质上不是这个示例,但是以下代码是更著名的演示之一。它必须使用Release版本进行编译并在调试器之外运行。错误是程序没有结束。您可以通过

Thread.MemoryBarrier
while
循环内调用或标记
stop
为来修复该错误
volatile

class Program{    static bool stop = false;    public static void Main(string[] args)    {        var t = new Thread(() =>        { Console.WriteLine("thread begin"); bool toggle = false; while (!stop) {     toggle = !toggle; } Console.WriteLine("thread end");        });        t.Start();        Thread.Sleep(1000);        stop = true;        Console.WriteLine("stop = true");        Console.WriteLine("waiting...");        t.Join();    }}

之所以难以重现某些线程错误,是因为您用来模拟线程交织的相同策略实际上可以修复该错误。

Thread.Sleep
是最著名的示例,因为它会产生内存障碍。您可以通过在
while
循环中放置一个调用并观察该错误消失来验证这一点。

您可以在此处看到我的答案,以对您引用的书中的示例进行其他分析。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/442724.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号