CodeQL 文档

不一致的锁顺序

ID: cs/inconsistent-lock-sequence
Kind: problem
Security severity: 
Severity: error
Precision: high
Tags:
   - reliability
   - correctness
   - concurrency
   - external/cwe/cwe-662
Query suites:
   - csharp-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

应以一致的顺序锁定并发持有的锁,否则程序可能会死锁。此规则检测嵌套的 lock 语句,这些语句在程序的不同部分以不同的顺序锁定变量。

建议

可以通过确保嵌套的 lock 语句始终以相同的顺序锁定变量来避免此问题。

示例

以下示例显示了一个运行两个线程的程序,该程序由于 thread1 持有 lock1 并等待获取 lock2 而死锁,而 thread2 持有 lock2 并等待获取 lock1

using System;
using System.Threading;

class Deadlock
{
    private readonly Object lock1 = new Object();
    private readonly Object lock2 = new Object();

    public void thread1()
    {
        lock (lock1)
        {
            Console.Out.WriteLine("Thread 1 acquired lock1");
            Thread.Sleep(10);
            Console.Out.WriteLine("Thread 1 waiting on lock2");
            lock (lock2)    // Deadlock here
            {
            }
        }
    }

    public void thread2()
    {
        lock (lock2)
        {
            Console.Out.WriteLine("Thread 2 acquired lock2");
            Thread.Sleep(10);
            Console.Out.WriteLine("Thread 2 waiting on lock1");
            lock (lock1)    // Deadlock here
            {
            }
        }
    }
}

通过如下所示对 lock 变量重新排序,可以解决此问题。

using System;
using System.Threading;

class DeadlockFixed
{
    private readonly Object lock1 = new Object();
    private readonly Object lock2 = new Object();

    public void thread1()
    {
        lock (lock1)
        {
            Console.Out.WriteLine("Thread 1 acquired lock1");
            Thread.Sleep(10);
            Console.Out.WriteLine("Thread 1 waiting on lock2");
            lock (lock2)
            {
            }
        }
    }

    public void thread2()
    {
        lock (lock1)    // Fixed
        {
            Console.Out.WriteLine("Thread 2 acquired lock1");
            Thread.Sleep(10);
            Console.Out.WriteLine("Thread 2 waiting on lock2");
            lock (lock2)    // Fixed
            {
            }
        }
    }
}

参考

  • ©GitHub 公司
  • 条款
  • 隐私