【问题标题】:What are the advantages of using `lock` over `SemaphoreSlim`?使用 `lock` 相对于 `SemaphoreSlim` 有什么优势?
【发布时间】:2022-11-22 03:18:40
【问题描述】:

我参加聚会迟到了,但我最近了解到SemaphoreSlim

我曾经使用 lock 进行同步锁定,使用 busy 布尔值进行异步锁定。现在我只使用SemaphoreSlim 来处理所有事情。

private SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);

private void DoStuff()
{
    semaphoreSlim.Wait();
    try
    {
        DoBlockingStuff();
    }
    finally
    {
        semaphoreSlim.Release();
    }
}

对比

private object locker = new object();

private void DoStuff()
{
    lock(locker)
    {
        DoBlockingStuff();
    }
}

有没有我更喜欢使用lock而不是SemaphoreSlim的同步情况?如果有,它们是什么?

【问题讨论】:

  • @Evk 我认为 linked question 在两个方面与这个问题不同。这个问题是关于SemaphoreSlim,而不是关于Semaphore。这个问题还询问了一般的优势,而不仅仅是性能。
  • @TheodorZoulias 没问题,尽管该问题中未被接受的答案在术语或性能方面将 SemaphoreSlim 与锁进行了比较。但如果有人认为它不是重复的——我不反对。
  • @Evk 是的,我看到 accepted answer 与这个问题相关。但那个答案在那里也是题外话。对于这些情况,quidance 有点含糊。

标签: c# multithreading thread-safety locking semaphore


【解决方案1】:

以下是 lock 相对于 SemaphoreSlim 的一些优势:

  1. lock 是可重入的,而 SemaphoreSlim 不是。所以使用 lock 编程更容易。如果你的应用程序中有一条罕见的路径,你两次获取相同的锁,lock 将成功获取它,而 SemaphoreSlim 将死锁。

  2. 您可以使用lock 编写更健壮的代码,因为您可以在已获取锁的辅助方法中添加调试断言:Debug.Assert(Monitor.IsEntered(_locker));

  3. lockMonitor 类的语法糖。换句话说,在 C# 中有对 Monitor 的语言支持,而没有对 SemaphoreSlim 的语言支持。所以使用lock 相对来说更方便也更简洁。

  4. lock 可以在线程中止的情况下存活。它由 C# 编译器翻译like this

        bool lockTaken = false;
        try
        {
            Monitor.Enter(obj, ref lockTaken);
            DoBlockingStuff();
        }
        finally
        {
            if (lockTaken)
            {
                Monitor.Exit(obj);
            }
        }
    

    Monitor.Enter 已经过仔细编码,以便在线程中止的情况下,lockTaken 将具有正确的值。相反SemaphoreSlim.Wait是在try/finally块之外调用的,所以有一个小窗口可以中止当前线程而不释放锁,从而导致死锁。

    .NET 平台已放弃对 Thread.Abort 方法的支持,因此您可以正确地说最后一点仅具有理论价值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 2012-08-22
    相关资源
    最近更新 更多