《Advanced .NET Debugging》 读书笔记 Listing 6-4: Deadlock的简单示例
时间:2011-01-09 来源:李志鹏
using System;
using System.Text;
using System.Threading;
namespace Advanced.NET.Debugging.Chapter6
{
internal class DBWrapper1
{
private string connectionString;
public DBWrapper1(string conStr)
{
this.connectionString = conStr;
}
}
internal class DBWrapper2
{
private string connectionString;
public DBWrapper2(string conStr)
{
this.connectionString = conStr;
}
}
class Deadlock
{
private static DBWrapper1 db1;
private static DBWrapper2 db2;
static void Main(string[] args)
{
db1 = new DBWrapper1("DBCon1");
db2 = new DBWrapper2("DBCon2");
Thread newThread = new Thread(ThreadProc);
newThread.Start();
Thread.Sleep(2000);
lock (db2)
{
Console.WriteLine("Updating DB2");
Thread.Sleep(2000);
lock (db1)
{
Console.WriteLine("Updating DB1");
}
}
}
private static void ThreadProc()
{
Console.WriteLine("Start worker thread");
lock (db1)
{
Console.WriteLine("Updating DB1");
Thread.Sleep(3000);
lock (db2)
{
Console.WriteLine("Updating DB2");
}
}
Console.WriteLine("Out");
}
}
}
Main函数线程会先sleep2秒,然后锁定db2对象,接着休息2秒,再试图锁定db1对象。而此时,db1对象已经被锁定,会在sleep3秒以后尝试锁定db2。现在的结果就是main线程拿不到db1,因为db1被ThreadProc线程占据,Main线程进入suspend状态;ThreadProc线程拿不到db2,因为db2被main线程占据,ThreadProc线程也进入了suspend状态。此时两个线程都进入了suspend状态,程序无法继续。
1. 在WinDbg下载入 Deadlock.exe
2. 在程序运行运行几秒进入思索状态以后,执行 .loadby sos.dll mscorwks
3. 载入 .load sosex.dll
4. 执行 !dlk
可见此时线程0x1占有db2,试图获取db1; 线程0x3占有db1, 试图占有db2。与分析符合。