gpt4 book ai didi

c# - 使用 Thread.Sleep 解决锁定死锁

转载 作者:行者123 更新时间:2023-11-30 19:24:46 25 4
gpt4 key购买 nike

如果我在 Thread.Sleep(0) 方法中注释或传递 0,则不会出现死锁。在其他情况下会出现死锁。 uptask 由线程轮询中的线程执行,这需要一些时间。同时,主线程获取 lockB、lockA 并打印字符串并释放锁。之后 uptask 开始运行,它发现 lockA 和 lockB 是空闲的。所以在这种情况下不存在死锁。但是如果我同时 sleep 主线程 uptask 前进并看到 lockB 被锁定并且发生死锁。谁能更好地解释或验证这是否是原因?

class MyAppClass
{
public static void Main()
{
object lockA = new object();
object lockB = new object();
var uptask = Task.Run(() =>
{
lock (lockA)
{
lock (lockB)
{
Console.WriteLine("A outer and B inner");
}
}
});
lock (lockB)
{
//Uncomment the following statement or sleep with 0 ms and see that there is no deadlock.
//But sleep with 1 or more lead to deadlock. Reason?
Thread.Sleep(1);
lock (lockA)
{
Console.WriteLine("B outer and A inner");
}
}
uptask.Wait();
Console.ReadKey();
}
}

最佳答案

您真的不能依赖 Thread.Sleep 来防止死锁。它在您的环境中工作了一段时间。它可能不会一直工作,也可能不会在其他环境中工作。

由于您是以相反的顺序获取锁,因此存在死锁的可能性。

为防止死锁,请确保按顺序获取锁(例如,在两个线程中先是 lockA,然后是 lockB)。

我对发生这种情况的最佳猜测是,如果您不休眠,那么主线程将在另一个线程(来自线程池)获得 lockA 之前获得并释放这两个锁。请注意,在线程池上调度和运行任务需要一些时间。在大多数情况下,它是可以忽略的。但对于您的情况,它有所作为。

要验证这一点,请在 uptask.Wait() 之前添加以下行:

Console.WriteLine("main thread is done");

从线程池线程获取 lockA 后的这一行:

Console.WriteLine("Thread pool thread: obtained lockA");

在没有死锁的情况下,在线程池线程将其消息打印到控制台之前,您将看到第一条消息打印到控制台。

关于c# - 使用 Thread.Sleep 解决锁定死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33302906/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com