为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
泛舟湖上清波郎朗 2022-01-09 10:28:59
这是我感到困惑的标准部分:http : //www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf#page=178&zoom=auto,87,610%222.1。如果类型尚未初始化,请尝试获取初始化锁。2.2.1。如果不成功,查看该线程或等待该线程完成的任何线程是否已经持有锁。2.2.2。如果是这样,则返回,因为阻塞会造成死锁。该线程现在将看到该类型的未完全初始化状态,但不会出现死锁。以下代码在我测试时出现死锁,这似乎与标准相矛盾: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();    }}根据标准,我预计会发生以下情况:主线程获取 Foo 的初始化锁。主线程运行 Foo 的静态构造函数。主线程创建 otherThread 并启动它。otherThread 开始等待一秒钟,从而确保第 5 点发生在第 6 点之前。主线程开始等待 otherThread 完成。otherThread 尝试在 Foo 上获取初始化锁,但由于主线程持有锁而失败。otherThread 放弃执行静态构造函数,因为主线程持有初始化锁并等待 otherThread。otherThread 运行 SomeFunction 并成功完成。主线程返回。这里有什么问题?
查看完整描述

1 回答

?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

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


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


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();

}

这个例子没有死锁,因为一个线程正在等待另一个线程释放静态初始化器锁,所以当该线程最终要求原始线程拥有的静态初始化器锁时,quoted 子句启动并且它只是跳过锁.


查看完整回答
反对 回复 2022-01-09
  • 1 回答
  • 0 关注
  • 212 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号