【问题标题】:is it possible to generate a deadlock with single lock是否可以使用单锁生成死锁
【发布时间】:2013-11-18 21:42:27
【问题描述】:

这是一道面试题。 一般来说,当thread1锁定mutex1时,会产生2个线程之间的死锁,而在它试图锁定mutex2之前,线程2会锁定mutex2。之后tread 2想要锁定mutex1。所以他们永远互相等待。

问题是“你能给出一个使用一个互斥锁和任意数量的线程的死锁场景吗?”

【问题讨论】:

    标签: multithreading mutex deadlock


    【解决方案1】:

    死锁需要 4 件事:

    互斥 - 指拥有可以由单个线程拥有的资源(锁)的想法。
    无抢占 - 无法强制获取锁
    循环等待 - 指一个线程等待另一个线程,即等待自身(或链)
    Hold and Wait - 一个线程可以获取一个锁并等待另一个

    在面试中,向他们展示你的思维过程通常更重要,如果你提出这些规则,他们可能会比试图给出一个“技术上正确”的技巧答案更能帮助你。

    你可以这样做,不过:
    主线程锁定一个资源,然后将一些任务发送到线程池。这些任务等待资源。主线程等待任务。

    【讨论】:

    • “等待任务”,“等待资源”。我认为这更好地暴露了 Yakov 理解中的一个缺陷:导致死锁的不是锁,而是在等待某些东西(无论是锁还是其他任何东西)。
    【解决方案2】:

    这样的?使用 1 个互斥体 和 1 个线程获得死锁:

    #define LOCK(std_mutex)    std::lock_guard<std::mutex> LOCK_GUARD(std_mutex)
    std::mutex lock;
    
    int main ()
    {
        LOCK(lock);
    
        {
            LOCK(lock); //deadlock...
        }
    
        std::cout<<"end"; //never goes here
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      我猜这取决于你如何定义“死锁”,但我可以看到一种可能性:

      1. 线程 A 获取互斥锁
      2. 线程 B 等待互斥体
      3. 线程 A 在未释放互斥锁的情况下死亡

      线程 B 永远不会运行。

      【讨论】:

      • 那只是一个糟糕的程序。但这是一个很好的面试答案!
      • 对了,线程 A 甚至可能不需要死就导致死锁:如果互斥锁获取和释放之间的代码抛出异常(在支持异常的语言中),并且释放是不在某种finally 块中,没有线程能够再次获得该锁。这听起来对我来说是一个完全有效的可能性,正如詹姆斯指出的那样,这是一个很好的面试问题。
      【解决方案4】:

      如果你有两个进程,即使没有任何锁,你也可能出现死锁情况:https://stackoverflow.com/a/17320443/145757

      【讨论】:

        【解决方案5】:

        我认为你不能只持有一个锁就出现死锁。但是,如果一个锁的持有时间超过了等待它的其他进程/线程的超时阈值,您可能会遇到超时。

        【讨论】:

          【解决方案6】:

          是的,您锁定了互斥锁或临界区,但忘记解锁它(比如在某个退出代码路径中)。尝试访问此代码的下一个线程是死锁。我刚遇到这种情况。

          【讨论】:

            【解决方案7】:

            当您考虑死锁(以及大多数线程主题)时,您不会考虑线程同步机制,而是考虑资源获取。您可以在没有任何互斥锁、事件或信号的情况下执行死锁,只需在循环中等待正确的资源状态,如果这种情况发生在所有可以修改您的资源的线程上,您就有了死锁。从这个角度来看,我认为正确的答案应该是这个问题被问得很糟糕。

            【讨论】:

              【解决方案8】:

              假设您的程序使用中断处理程序。正常程序锁定一个资源。并且在释放锁之前发生中断。并且中断处理程序也想锁定该资源。这可能会导致中断处理程序永远不会返回,您的程序也不会恢复。

              基本上仍然是两方试图使用相同的资源。但是即使在单线程环境中,您也无法阻止中断的发生。

              【讨论】:

                猜你喜欢
                • 2020-11-01
                • 2019-02-23
                • 1970-01-01
                • 1970-01-01
                • 2018-06-10
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多