我有一个 ASP.NET Core 3.1 Web API 应用程序,它有一个后台主机服务,我在其中编写了以下代码来模拟应用程序的死锁:
public class Worker : IHostedService
{
public Task StartAsync(CancellationToken cancellationToken)
{
var a = new object();
var b = new object();
lock (a)
{
lock (b)
{
}
}
// other thread
lock (b)
{
lock (a)
{
}
}
return Task.CompletedTask;
}
}
应用程序正在运行,但应用程序不会陷入死锁或挂起状态,我仍然可以访问 Web API 端点,结果会返回给我。
是否有可能使正在运行的 Web 应用程序陷入死锁或挂起状态,以便没有任何 API 给出任何 200 结果?
Thanks.
如所写,当前方法将NEVER僵局。
锁对象对于方法来说是本地的。正确的锁定必须使用方法范围之外的对象。
在以下版本中,锁对象对于类来说是静态的,并且锁定会添加微小的延迟来模拟正在执行的工作。在这种情况下,应用程序将与该方法的第二个入口发生死锁。
public class Worker
{
private static readonly object _a = new();
private static readonly object _b = new();
private const int _delay = 5;
public Task StartAsync2( int n )
{
lock( _a )
{
Console.WriteLine( $"{n}: _a1 enter" );
lock( _b )
{
Console.WriteLine( $"{n}: _b1 enter" );
Thread.Sleep( _delay );
}
Console.WriteLine( $"{n}: _b1 exit" );
}
Console.WriteLine( $"{n}: _a1 exit" );
// other thread
lock( _b )
{
Console.WriteLine( $"{n}: _b2 enter" );
lock( _a )
{
Console.WriteLine( $"{n}: _a2 enter" );
Thread.Sleep( _delay );
}
Console.WriteLine( $"{n}: _a2 exit" );
}
Console.WriteLine( $"{n}: _b2 exit" );
return Task.CompletedTask;
}
}
下面是如何执行Worker
导致死锁:
var w = new Worker();
var t = new Task[5];
for( int i = 0; i < t.Length; i++ )
{
int n = i;
t[i] = Task.Run( () =>
{
Console.WriteLine( $"{n} start" );
w.StartAsync2( n );
Console.WriteLine( $"{n} end" );
return Task.CompletedTask;
} );
}
Task.WaitAll( t );
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)