【问题标题】:Semaphore lock resulting in a deadlock [duplicate]信号量锁导致死锁[重复]
【发布时间】:2021-05-09 11:06:12
【问题描述】:
public class SampleData
{
 private static readonly Semaphore pool = new Semaphore(0,1);

 public string Data => getFromFile();

 private static string getFromFile()
 {
   pool.WaitOne();
   var data = 
   File.ReadAllText("somefilepath");
    pool.Release();
    return data;
  }
}

在程序.cs中

var tasks = new List<Task<string>>();
for(int i=0; i<=5; i++)
{
   tasks.Add(Task.Run<string>(()=> 
    new SampleData().Data));
}

Task.WaitAll(tasks.ToArray());

当我运行它时,它永远不会完成任务。谁能告诉我这里有什么问题?

谢谢。

【问题讨论】:

标签: c# .net multithreading task


【解决方案1】:

如果 getFromFile() 抛出异常,信号量将永远不会被释放,Task.WaitAll 将永远等待,您需要将 pool.Release() 移动到 finally 部分。这可能是无限期等待的原因。

private static string getFromFile()
 {
   pool.WaitOne();
   try {
     var data = File.ReadAllText("somefilepath");
     return data;
   }
   finally {
     pool.Release();
   }
  }
}

【讨论】:

    【解决方案2】:

    首先

    如果这不是跨进程,您应该考虑使用SemaphoreSlim

    其次

    关于您对Semaphore(0,1) 的初始化。如果initialCount 小于maximumCount,则效果与当前线程调用WaitOne (maximumCount 减去initialCount) 次相同。

    也就是说,当您在当前配置中调用 pool.WaitOne(); 时,您将阻塞直到有人调用 release(直接)。

    例如:

    private static readonly Semaphore pool = new Semaphore(0,1);
    
    static void Main(string[] args)
    {
       pool.WaitOne();
       Console.WriteLine("This will never get executed");
    }
    

    你可能想要:

    Semaphore(1,1)
    // or
    SemaphoreSlim(1,1)
    

    最后

    您必须始终将这些同步原语包装在try finally 中,否则您异常中最终死锁em> 在Release 之前被抛出。

    SemaphoreSlim

    await pool.WaitAsync();
    try
    {
       // do something
    }
    finally
    {
       pool.Release();
    }
    

    或者如果你真的需要使用Semaphore

    pool.WaitOne();
    try
    {
    
      // do something
    }
    finally
    {
       pool.Release();
    }
    

    【讨论】:

      猜你喜欢
      • 2014-04-24
      • 1970-01-01
      • 2021-03-20
      • 1970-01-01
      • 1970-01-01
      • 2019-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多