我正在尝试创建一个处理工作队列的系统。该系统具有以下规格:
- 该系统有两个组件:工作分配器和工作人员。
- 同时运行的worker数量有一个设定的上限。该上限大于一。
- 为了避免同一任务被执行两次的问题,只有一个工作分配者。
您会使用什么设计来创建这样的系统?这是我的想法:
- 创建队列集合,每个工作人员一个队列
- 为工作分配者创建一个计时器。它的工作是填充队列。
- 为每个worker创建一个Timer,传入一个队列对象作为对象状态来表示其工作负载
- 在队列锁定时将其删除并添加到队列中。
- 使用锁定时递增和递减的计数器,以确保同时运行的工作任务数量不超过指定数量。
我觉得必须有更好的方法来做到这一点。你会推荐什么?我应该为工作人员从计时器切换到线程吗?当队列为空时,线程是否应该旋转/等待?线程是否应该关闭并让工作分配者有条件地创建一个新线程?
我不知道你的任务将运行多长时间,但似乎最好的办法是使用ThreadPool。
此外,我只会使用并且实际上已经使用了一个中央队列——仅此一项就可以消除一些复杂性。
我有一个线程处理队列并对项目执行操作(在您的情况下,它将对任务进行排队)。
至于使队列线程安全,System.Collections.Concurrent 中有一个 ConcurrentQueue 用于此目的(msdn http://msdn.microsoft.com/en-us/library/dd267265.aspx, 基准测试与锁定队列 http://geekswithblogs.net/BlackRabbitCoder/archive/2010/06/07/c-system.collections.concurrent.concurrentqueue-vs.-queue.aspx).
现在,放入一个 BlockingCollection (msdn http://msdn.microsoft.com/en-us/library/dd997371.aspx)并且您拥有所需的一切。
BlockingCollection<Packet> sendQueue = new BlockingCollection<Packet>(new ConcurrentQueue<Packet>());
while (true)
{
var packet = sendQueue.Take(); //this blocks if there are no items in the queue.
ThreadPool.QueueUserWorkItem(state =>
{
var data = (Packet)state;
//do whatever you have to do
}, packet );
}
某处有一些东西sendQueue.Add(packet);
总结,
- 所有“工人”的一个队列
- 一个线程从队列中出队
并将其传递给线程池。
我想就是这样。
ps:如果你必须控制线程数量,请按照josh3736的建议使用“智能线程池”
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)