C# 为什么ReaderWriterLock在所有者线程终止时不自动释放/退出?

C# 为什么ReaderWriterLock在所有者线程终止时不自动释放/退出?,c#,multithreading,C#,Multithreading,这是一个理论问题,;我没有一个实际的问题要解决,我只是想了解这种工作方式背后的原因 我发现,如果一个线程没有退出ReaderWriterLock,那么即使在原始线程终止后,其他线程也无法获得锁。当拥有锁的线程终止时,ReaderWriterLock没有向等待的线程授予锁,这有什么好的原因吗 下面是一个演示该问题的测试用例 static void Main(string[] args) { ReaderWriterLockSlim readerWriterLock

这是一个理论问题,;我没有一个实际的问题要解决,我只是想了解这种工作方式背后的原因

我发现,如果一个线程没有退出ReaderWriterLock,那么即使在原始线程终止后,其他线程也无法获得锁。当拥有锁的线程终止时,ReaderWriterLock没有向等待的线程授予锁,这有什么好的原因吗

下面是一个演示该问题的测试用例

    static void Main(string[] args)
    {
        ReaderWriterLockSlim readerWriterLock = new ReaderWriterLockSlim();

        Thread t1 = new Thread((a) =>
        {
            readerWriterLock.EnterReadLock();

            // this thread omits to Exit the lock....
        });

        Thread t2 = new Thread((a) =>
        {
            readerWriterLock.EnterWriteLock();
        });

        t1.Start();
        t2.Start();

        // wait for all threads to finish
        t1.Join();
        t2.Join();
    }

简单的答案是:编写器线程无法轻松地知道读线程已终止,同时也会使锁定操作变得昂贵

锁通常作为内存中的值来实现,因此获取释放锁的命令需要更改这些值。如果一个线程设置了获取锁的值,然后崩溃,那么获取另一个锁的唯一方法就是让某个后台线程轮询死线程,查看最近获取的锁的列表,然后清除它们


除此之外,这种方法成本高昂且需要大量的管道,还可能不安全,因为您不知道线程崩溃前到底走了多远。

锁可能不太难存储独占持有它的线程的标识,或者存储非独占持有它的线程列表。然后,锁定代码可以在被阻止时定期检查,以查看阻止它的任何或所有线程是否仍处于活动状态。这样做的最大问题是线程没有标准的方法来指示受锁保护的实体在什么时刻处于合法状态或无效状态。如果持有锁的线程在受保护实体处于无效状态时死亡,则应继续禁止访问这些实体,除非或直到某些代码知道如何处理损坏。

在崩溃的线程上下文中,我同意假设它锁定的资源现在处于干净状态是有风险的。但在正常线程终止的情况下,我认为这样的假设是安全的。关于性能,他们可以提供两种实现:一种是我们现在拥有的,另一种是实现自动发布的较慢但更智能的。无论如何,谢谢你的回答,我想你所解释的确实是这样做的原因。R:正常的线程终止,你可以考虑使用一个RAII模式来锁定,这有助于确保在退出某个范围后释放一个锁。在C#中,可以使用lock关键字(用于常规锁)或try/finally块(用于ReaderWriterLock),以确保在范围退出时释放锁。同样,如果线程崩溃,或者调用了某个较低级别的线程退出函数,这将无助于您,但它将有助于降低因编程错误而导致死锁的风险,在编程错误中,您会忘记释放某些复杂代码路径上的锁。