【问题标题】:Questions about ReaderWriterLockSlim. I use readerwriterlockslim to read and write, but only show write at last in console. Why?关于 ReaderWriterLockSlim 的问题。我使用 readerwriterlockslim 进行读写,但最后只在控制台中显示 write。为什么?
【发布时间】:2020-06-01 06:41:02
【问题描述】:

这是代码:

class program
{
    static ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();
    static void Main(string[] args)
    {
        for (int i = 0; i < 2; i++)
        {
            Task.Factory.StartNew(Read);
        }
        for (int i = 0; i < 1; i++)
        {
            Task.Factory.StartNew(Write);
        }
        Console.Read();
    }

    static void Read()
    {
        while (true)
        {
            rwLock.EnterReadLock();;
            Thread.Sleep(100);
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}  reading");
            rwLock.ExitReadLock();
        }
    }
    static void Write()
    {
        while (true)
        {
            rwLock.EnterWriteLock();
            Thread.Sleep(3000);
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} writing");
            rwLock.ExitWriteLock();
        }
    }
}

我想测试ReaderWriterLockSlim,我期望的结果是在控制台中交替读取和写入,但最后只能在控制台中写入。

结果如下:

5 reading 2020/2/17 18:24:36
4 reading 2020/2/17 18:24:36
3 reading 2020/2/17 18:24:36
6 writing 2020/2/17 18:24:39
6 writing 2020/2/17 18:24:42
6 writing 2020/2/17 18:24:45
6 writing 2020/2/17 18:24:48
6 writing 2020/2/17 18:24:51
6 writing 2020/2/17 18:24:54
6 writing 2020/2/17 18:24:57
6 writing 2020/2/17 18:25:00
6 writing 2020/2/17 18:25:03
6 writing 2020/2/17 18:25:06

但是当使用 ReaderWriterLock 时,它的替代显示。结果如下:

4 reading 2020/2/17 18:30:22
3 reading 2020/2/17 18:30:22
5 reading 2020/2/17 18:30:22
6 writing 2020/2/17 18:30:25
4 reading 2020/2/17 18:30:25
3 reading 2020/2/17 18:30:25
5 reading 2020/2/17 18:30:25
6 writing 2020/2/17 18:30:28
4 reading 2020/2/17 18:30:29
5 reading 2020/2/17 18:30:29
3 reading 2020/2/17 18:30:29
6 writing 2020/2/17 18:30:32
4 reading 2020/2/17 18:30:32
5 reading 2020/2/17 18:30:32
3 reading 2020/2/17 18:30:32
6 writing 2020/2/17 18:30:35
5 reading 2020/2/17 18:30:35
3 reading 2020/2/17 18:30:35
4 reading 2020/2/17 18:30:35
6 writing 2020/2/17 18:30:38
5 reading 2020/2/17 18:30:45
3 reading 2020/2/17 18:30:45
4 reading 2020/2/17 18:30:45

为什么会发生这种情况,有人告诉我这种现象的原因吗? 希望回答

【问题讨论】:

  • 似乎像一个“公平政策”的问题;请参阅remarks here - 它建议 net48 政策试图平衡作者和读者;你在这里的确切框架是什么?然而它也说,只要有单个线程处于写入模式或试图进入写入模式,处于读取模式的线程就会被阻塞......
  • 是的,我要表达的是阅读模式被屏蔽了
  • 这是一个称为饥饿的锁定问题。读者获取锁的时间非常短。正如this blog post 中所述,RWLS 偏爱作家并饿死读者。

标签: c# readerwriterlockslim readerwriterlock


【解决方案1】:

这里的问题是 thread.Sleep() 在临界区内被调用。 这会导致写入器线程每次将锁保持 3 秒,并在写入器线程重新获取锁的非常短的时间内释放它,因为在这种情况下,显然 ReaderWriterLockSlim 为写入器提供了更好的优先级。

我尝试在释放锁后调用 Thread.Sleep(),一切正常。

class LockProgram
{
    static ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();
    static void Main(string[] args)
    {
        for (int i = 0; i < 2; i++)
        {
            Task.Factory.StartNew(Read);
        }
        for (int i = 0; i < 1; i++)
        {
            Task.Factory.StartNew(Write);
        }
        Console.Read();
    }

    static void Read()
    {
        while (true)
        {
            rwLock.EnterReadLock(); ;                
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}  reading");
            rwLock.ExitReadLock();
            Thread.Sleep(100);
        }
    }
    static void Write()
    {
        while (true)
        {
            rwLock.EnterWriteLock();                
            Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} writing");
            rwLock.ExitWriteLock();
            Thread.Sleep(3000);
        }
    }
}

值得查看ReaderWriterLockSlimReaderWriterLock 的.Net 参考源

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-15
    • 2020-08-18
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    相关资源
    最近更新 更多