gpt4 book ai didi

c# - C# 中的静态构造函数死锁是否与 ECMA CLI 标准相矛盾?

转载 作者:行者123 更新时间:2023-11-30 22:59:25 26 4
gpt4 key购买 nike

这是我感到困惑的标准部分:http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf#page=178&zoom=auto,87,610%22

2.1. If the type is not yet initialized, try to take an initialization lock.

2.2.1. If not successful, see whether this thread or any thread waiting for this thread to complete already holds the lock.

2.2.2. If so, return since blocking would create a deadlock. This thread will now see an incompletely initialized state for the type, but no deadlock will arise.

下面的代码在我测试的时候死锁了,这似乎与标准相矛盾:

public static class Foo {
static Foo() {
var otherThread = new Thread(() => { Thread.Sleep(1000); SomeFunction(); });
otherThread.Start();
otherThread.Join();
}
public static void SomeFunction() {
}
}
class Program {
static void Main() {
Foo.SomeFunction();
}
}

根据标准,我预计会发生以下情况:

  1. 主线程获取 Foo 上的初始化锁。
  2. 主线程运行 Foo 的静态构造函数。
  3. 主线程创建 otherThread 并启动它。
  4. otherThread 开始等待一秒钟,从而确保第 5 点发生在第 6 点之前。
  5. 主线程开始等待其他线程完成。
  6. otherThread 尝试获取 Foo 上的初始化锁,但由于主线程持有锁而失败。
  7. otherThread 放弃执行静态构造函数,因为主线程持有初始化锁并等待 otherThread。
  8. otherThread 运行 SomeFunction 并成功完成。
  9. 主线程返回。

这里有什么问题吗?

最佳答案

“等待此线程完成的任何线程”指的是任何使用静态线程的初始化锁等待的线程,而不是使用任何可能的同步机制等待的线程。静态初始化机制无法知道某个其他线程正在等待另一个线程上的使用一些完全不同的机制

引用的部分是指以下示例不会死锁的事实:

public class A
{
static A()
{
Thread.Sleep(TimeSpan.FromSeconds(1));
B.DoNothing();
}
public static void DoNothing() { }
}
public class B
{
static B()
{
Thread.Sleep(TimeSpan.FromSeconds(1));
A.DoNothing();
}
public static void DoNothing() { }
}
private static void Main()
{
Task.Run(() => B.DoNothing());
A.DoNothing();
}

这个例子没有死锁,因为一个线程正在等待另一个线程释放静态初始化器锁,所以当该线程结束请求原始线程拥有的静态初始化器锁时,引用的子句开始,它只是跳过锁。

关于c# - C# 中的静态构造函数死锁是否与 ECMA CLI 标准相矛盾?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52229614/

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