【发布时间】:2013-11-18 21:42:27
【问题描述】:
这是一道面试题。 一般来说,当thread1锁定mutex1时,会产生2个线程之间的死锁,而在它试图锁定mutex2之前,线程2会锁定mutex2。之后tread 2想要锁定mutex1。所以他们永远互相等待。
问题是“你能给出一个使用一个互斥锁和任意数量的线程的死锁场景吗?”
【问题讨论】:
标签: multithreading mutex deadlock
这是一道面试题。 一般来说,当thread1锁定mutex1时,会产生2个线程之间的死锁,而在它试图锁定mutex2之前,线程2会锁定mutex2。之后tread 2想要锁定mutex1。所以他们永远互相等待。
问题是“你能给出一个使用一个互斥锁和任意数量的线程的死锁场景吗?”
【问题讨论】:
标签: multithreading mutex deadlock
死锁需要 4 件事:
互斥 - 指拥有可以由单个线程拥有的资源(锁)的想法。
无抢占 - 无法强制获取锁
循环等待 - 指一个线程等待另一个线程,即等待自身(或链)
Hold and Wait - 一个线程可以获取一个锁并等待另一个
在面试中,向他们展示你的思维过程通常更重要,如果你提出这些规则,他们可能会比试图给出一个“技术上正确”的技巧答案更能帮助你。
你可以这样做,不过:
主线程锁定一个资源,然后将一些任务发送到线程池。这些任务等待资源。主线程等待任务。
【讨论】:
这样的?使用 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;
}
【讨论】:
我猜这取决于你如何定义“死锁”,但我可以看到一种可能性:
线程 B 永远不会运行。
【讨论】:
finally 块中,没有线程能够再次获得该锁。这听起来对我来说是一个完全有效的可能性,正如詹姆斯指出的那样,这是一个很好的面试问题。
如果你有两个进程,即使没有任何锁,你也可能出现死锁情况:https://stackoverflow.com/a/17320443/145757
【讨论】:
我认为你不能只持有一个锁就出现死锁。但是,如果一个锁的持有时间超过了等待它的其他进程/线程的超时阈值,您可能会遇到超时。
【讨论】:
是的,您锁定了互斥锁或临界区,但忘记解锁它(比如在某个退出代码路径中)。尝试访问此代码的下一个线程是死锁。我刚遇到这种情况。
【讨论】:
当您考虑死锁(以及大多数线程主题)时,您不会考虑线程同步机制,而是考虑资源获取。您可以在没有任何互斥锁、事件或信号的情况下执行死锁,只需在循环中等待正确的资源状态,如果这种情况发生在所有可以修改您的资源的线程上,您就有了死锁。从这个角度来看,我认为正确的答案应该是这个问题被问得很糟糕。
【讨论】:
假设您的程序使用中断处理程序。正常程序锁定一个资源。并且在释放锁之前发生中断。并且中断处理程序也想锁定该资源。这可能会导致中断处理程序永远不会返回,您的程序也不会恢复。
基本上仍然是两方试图使用相同的资源。但是即使在单线程环境中,您也无法阻止中断的发生。
【讨论】: