首先,我对一份冗长的请求道歉。
我有一个带有多个线程的基础结构,每个线程都在WaitHandle(AutoResetEvent)上等待,直到一个活动排队到它。我正在考虑改变基础设施,原因如下。每个线程都在自己的活动中工作。 (我有一系列不同的活动需要管理)。
我认为当前基础架构的缺点是我拥有与线程(活动)本身一样多的等待句柄以及哪些(线程数)可以保持增加或减少。
目前的逻辑如下 一组线程,每个线程都与自己的AutoResetEvent&活动 线程1 - 事件1,活动1 线程2-事件2-活性2
Activity
{
Thread th;
AutoResetEvent ev;
Operation();
}
每个线程执行一个循环并在循环中执行操作。
伪代码如下。
while(event.Wait())
{
//Execute operation (activity-n)
}
因此,将操作排入线程的控制器只是设置事件,线程完成其任务并返回等待下一个activity-n请求
Activity.event.Set();
我想减少所使用的WaitHandles数量的基础设施是在所有线程中使用一个信号量。
将信号量计数设置为任意最大值100.将信号量的初始计数设置为0.
Semaphore sem = new Semaphore(0,100);
Thread [] threads = new Threads(100);
现在信号量基本上处于所有线程的锁定状态。
所有线程现在都像以前一样执行循环
while(sem.Wait())
{
//deque activity
//perform activity
}
除了活动没有固定的线程(活动排队到集中式并发队列)。 对活动进行排队的控制器执行以下操作。
queue.Enqueue(activity-n);
//To release one of the threads from the waiting threads to execute the activity.
semaphore.Release(1).
信号量实现是否优于多个WaitHandle方法? 如果是这样的话? 我确实认为单一的信号量方法意味着增加了争用。
如果有人能对此有所了解。这会很棒。
更新 我没有使用过BlockingCollection,因为我的请求排队有点独特。我有条件,我有多种活动(类型1到n),并且当一个类型n的活动被采取行动时,不能对相同类型的活动(比如n)采取行动。这就是为什么我最初每个活动类型有一个主题。我试图将涉及的等待句柄减少到1,这就是我试图查看信号量方法是否合适的原因。但是我担心的是,如果我去Semaphore路线,我将增加锁争用。在我的场景中,我可能会在任何时候激活一个或两个线程,这意味着所有剩余的线程将争夺已经打开的信号量中的一个或两个开放槽。