C++ 面试题 目录

C++ 中什么是死锁 (deadlock)?如何避免?

推荐答案

在C++中,死锁(deadlock)是指两个或多个线程在执行过程中,因为争夺资源而造成的一种互相等待的现象,导致这些线程都无法继续执行下去。死锁通常发生在多个线程同时持有某些资源,并且试图获取对方持有的资源时。

避免死锁的常见方法:

  1. 避免嵌套锁:尽量减少锁的嵌套使用,确保每个线程只持有一个锁。
  2. 锁的顺序:所有线程以相同的顺序获取锁,避免循环等待。
  3. 使用超时机制:在获取锁时设置超时,避免无限期等待。
  4. 使用RAII(资源获取即初始化):通过智能指针或RAII类管理锁的获取和释放,确保锁在作用域结束时自动释放。
  5. 死锁检测:通过算法或工具检测死锁的发生,并采取相应的措施。

本题详细解读

死锁的四个必要条件

死锁的发生通常需要满足以下四个条件,称为死锁的四个必要条件:

  1. 互斥条件:资源一次只能被一个线程占用。
  2. 占有并等待:线程持有至少一个资源,并等待获取其他被占用的资源。
  3. 非抢占条件:已分配给线程的资源不能被其他线程强行抢占,必须由线程自行释放。
  4. 循环等待条件:存在一个线程等待的循环链,每个线程都在等待下一个线程所占用的资源。

死锁示例

以下是一个简单的C++代码示例,展示了死锁的发生:

-- -------------------- ---- -------
-------- ----------
-------- --------
-------- -------

---------- -------
---------- -------

---- --------- -
    --------------------------- --------------
    ------------------------------------------------------------ -- ------
    --------------------------- --------------
    --------- -- ------- - -- -------- -- ----------
-

---- --------- -
    --------------------------- --------------
    ------------------------------------------------------------ -- ------
    --------------------------- --------------
    --------- -- ------- - -- -------- -- ----------
-

--- ------ -
    ----------- ------------
    ----------- ------------

    ----------
    ----------

    ------ --
-

在这个示例中,thread1thread2分别以不同的顺序获取mutex1mutex2,导致两个线程互相等待对方释放锁,从而发生死锁。

如何避免死锁

为了避免死锁,可以采取以下措施:

  1. 统一锁的顺序:确保所有线程以相同的顺序获取锁。例如,修改thread2的代码,使其先获取mutex1,再获取mutex2
  2. 使用std::lockstd::lock可以一次性锁定多个互斥量,避免死锁。例如:
  3. 使用std::scoped_lock:C++17引入了std::scoped_lock,它可以自动管理多个锁的获取和释放,避免死锁。例如:

通过这些方法,可以有效避免死锁的发生。

纠错
反馈