仅允许 N 个并发线程的函数

本文关键字:线程 函数 并发 | 更新日期: 2023-09-27 18:31:28

我有一个Visual Studio 2008 C# .NET 3.5项目,其中一个类侦听来自另一个多线程类的事件调用。我需要确保我的事件只允许同时访问最多 10 个线程。第 11 个线程应阻塞,直到 10 个线程中的一个完成。

myobj.SomeEvent += OnSomeEvent;
private void OnSomeEvent(object sender, MyEventArgs args)
{
    // allow up to 10 threads simultaneous access. Block the 11th thread.
    using (SomeThreadLock lock = new SomeThreadLock(10))
    {         
        DoUsefulThings(args.foo);
    }
}

我无法控制其他MyObj类,因此我无法在那里实现线程池。

实现这一点的最佳方法是什么?

谢谢保罗·

仅允许 N 个并发线程的函数

你想要信号量类。 简而言之,它是一个锁,任何时候只允许指定数量的呼叫者通过。

由于您不控制线程的创建,因此您需要小心死锁情况。 信号量不是重入感知的 - 如果给定线程多次进入信号量,它将占用多个插槽。 因此,如果调用方的每个线程多次进入信号量,则可能会出现死锁。

为此

使用Semaphore。构造函数参数对于那些刚刚被引入类的人来说有点令人困惑。第一个参数指定现在允许通过的初始线程数。第二个参数指定在任何给定时间允许通过的最大线程数。

myobj.SomeEvent += OnSomeEvent;
Semaphore semaphore = new Semaphore(10, 10);
private void OnSomeEvent(object sender, MyEventArgs args)
{
  semaphore.WaitOne();
  try
  {
    DoUsefulThings(args.foo);
  }
  finally
  {
    semaphore.Release();
  }
}
习惯上为此

使用信号量。 将其初始化为 10 个单位。 wait() 在 DoUsefulThings() 之前一个单位,在 sign() 之后一个单位。