使用简单的 C# 重现线程死锁

本文关键字:线程 死锁 简单 | 更新日期: 2023-09-27 18:33:08

我想我遇到了死锁问题...我的程序运行良好,但有时它没有响应...???.在源代码 (C#) 中。没有锁(对象)或阅读器编写器锁苗条...我确实尝试使用相同的对象(List)在2个线程中重现死锁,但没有成功。

int n = 0;                      
  List<int> temp = new List<int>();
  var up = new Thread(() =>{
     for (int i = 0; i < 100000; i++){
     n++;
     temp.Add(i);                   
}
});
var down = new Thread(() => {
    for (int i = 0; i < 100000; i++){
        n--;
         try{
           temp.Remove(i);
         }catch {
           Console.WriteLine("No item {0} to remove", i);
         }
        }
});
up.Start();
down.Start();
down.Join();
up.Join();
Console.WriteLine(String.Join(",",temp));

上面的狙击代码仍然可以正常工作,没有死锁..???有人可以帮助我使用相同的变量在没有锁(对象)或系统锁的情况下用 2 个线程重现死锁......

提前致谢

使用简单的 C# 重现线程死锁

List不是线程安全的,所以这将是导致问题的原因。应创建线程安全解决方案(使用 lock 或线程安全集合),而不是专注于重新创建死锁。这会告诉你什么?

通常在使用锁或同步时发生死锁。

最常见的死锁是从线程更新 GUI。喜欢:

Thread thread = new Thread( () => 
{ 
    Invoke(new Action(() => 
    {
        Label1.Text = "something";
    }));
});
thread.Start();
// this join will prevent the messageloop from running, but the invoke waits on the messageloop to execute it's action.
thread.Join();

但这不像你的情况。

我想你的意思是n在不同的线程上增加和减少(与改变列表相同)。这不是死锁,而是线程安全问题

即使你把锁放进去,你也不会在那里死锁。

object lockObj = new object();
 var up = new Thread(() =>
 {
     for (int i = 0; i < 100000; i++)
     {
         lock(lockObj)
         {
             n++;
             temp.Add(i);                   
         }
     }
 });
 var down = new Thread(() => 
 {
     for (int i = 0; i < 100000; i++)
     {
         lock(lockObj)
         {
             n--;
             try
             {
                 temp.Remove(0);
             }
             catch 
             {
                 Console.WriteLine("No item {0} to remove", i);
             }
         }
     }
});

但这会大大减慢这一进程。