gpt4 book ai didi

c# - 互锁 Monitor.Enter 和 Monitor.Exit block

转载 作者:太空狗 更新时间:2023-10-29 21:51:48 27 4
gpt4 key购买 nike

ECMA-335 规范规定如下:

*获取锁(System.Threading.Monitor.Enter 或进入同步方法)应隐式执行 volatile 读取操作,并释放锁(System.Threading.Monitor.Exit 或离开同步方法)应隐式执行 volatile 写操作。(...)

volatile 读取具有获取语义,这意味着读取保证发生在 CIL 指令序列中读取指令之后发生的任何内存引用之前。 volatile 写入具有释放语义,这意味着写入保证在 CIL 指令序列中写入指令之前的任何内存引用之后发生。*

这意味着编译器不能将语句移出 Monitor.Enter/Monitor.Exit block ,但不禁止将其他语句移入 block 中。也许,甚至可以将另一个 Monitor.Enter 移到 block 中(因为可以交换 volatile 写入后跟 volatile 读取)。因此,可以使用以下代码:

class SomeClass
{
object _locker1 = new object();
object _locker2 = new object();

public void A()
{
Monitor.Enter(_locker1);
//Do something
Monitor.Exit(_locker1);
Monitor.Enter(_locker2);
//Do something
Monitor.Exit(_locker2);
}

public void B()
{
Monitor.Enter(_locker2);
//Do something
Monitor.Exit(_locker2);
Monitor.Enter(_locker1);
//Do something
Monitor.Exit(_locker1);
}
}

, 变成等同于以下内容:

class SomeClass
{
object _locker1 = new object();
object _locker2 = new object();

public void A()
{
Monitor.Enter(_locker1);
//Do something
Monitor.Enter(_locker2);
Monitor.Exit(_locker1);
//Do something
Monitor.Exit(_locker2);
}

public void B()
{
Monitor.Enter(_locker2);
//Do something
Monitor.Enter(_locker1);
Monitor.Exit(_locker2);
//Do something
Monitor.Exit(_locker1);
}
}

,可能导致死锁?还是我遗漏了什么?

最佳答案

ECMA-335 规范比 what the CLR (and every other implementation) uses 弱很多.

我记得读过(这里说)微软首次尝试移植到 IA-64,使用较弱的内存模型。他们有太多自己的代码取决于双重检查锁定习惯用法(在较弱的内存模型下 is broken),他们只是在该平台上实现了更强的模型。

乔达菲有 a great post为我们普通人总结(实际的)CLR 内存模型。还有一个指向 MSDN 文章的链接,该文章更详细地解释了 CLR 与 ECMA-335 的区别。

我不认为这在实践中是个问题;假设 CLR 内存模型,因为其他人都这样做。此时没有人会创建一个弱的实现,因为大多数代码都会被破坏。

关于c# - 互锁 Monitor.Enter 和 Monitor.Exit block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6902612/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com