我有这个生产者/消费者代码:Monitor.Pulse丢失信号?
MAIN:
static void Main()
{
using(PCQueue q = new PCQueue(2))
{
for(int i = 0; i < 10; i++)
{
int itemNumber = i; // To avoid the captured variable trap
q.EnqueueItem(() = > {
Thread.Sleep(1000); // Simulate time-consuming work
Console.Write(" Task" + itemNumber);
});
}
Console.WriteLine("Enqueued 10 items");
Console.WriteLine("Waiting for items to complete...");
}
}
类:
public class PCQueue: IDisposable
{
readonly object _locker = new object();
Thread[] _workers;
Queue <Action> _itemQ = new Queue <Action>();
public PCQueue(int workerCount)
{
_workers = new Thread[workerCount];
// Create and start a separate thread for each worker
for(int i = 0; i < workerCount; i++)
(_workers[i] = new Thread(Consume)).Start();
}
public void Dispose()
{
// Enqueue one null item per worker to make each exit.
foreach(Thread worker in _workers) EnqueueItem(null);
}
public void EnqueueItem(Action item)
{
lock(_locker)
{
_itemQ.Enqueue(item); // We must pulse because we're
Monitor.Pulse(_locker); // changing a blocking condition.
}
}
void Consume()
{
while(true) // Keep consuming until
{ // told otherwise.
Action item;
lock(_locker)
{
while(_itemQ.Count == 0) Monitor.Wait(_locker);
item = _itemQ.Dequeue();
}
if(item == null) return; // This signals our exit.
item(); // Execute item.
}
}
}
问:
比方说执行的item();
需要很长的时间。
1) we enqueue a new work and pulse. (1 consumer is busy now)
2) we enqueue a new work and pulse. (second consumer is busy now)
3) we enqueue a new work and pulse.
现在呢?两个线程都很忙!
我know,脉冲会丢失(或不?)
是唯一的解决办法是将其更改为AutoResetEvent
?
System.Collections.Concurrent.BlockingCollection有什么问题?如果你想DIY,你可以使用System.Threading.Semaphore和一个锁。对于生产者 - 消费者队列来说,事件并不是一个合适的解决方案 - 我不知道为什么如此之多的开发者被欺骗使用它们来达到这个目的。 – 2012-08-02 13:48:02
@MartinJames没有错。我只想知道如何增强代码,并检查我的假设是否正确。 – 2012-08-02 13:49:07
@MartinJames我猜你必须问Joe Albahari关于你的问题.http://books.google.co.il/books?id = VENrFSQFco8C&pg = PA846&lpg = PA846&dq =%22 + To + avoid + the + captured + variable +阱%22&源= BL&OTS = 3uV-ribX9Q&SIG = gjsMPGyZD6H-DgcwjR_vuv5V8aI&HL = EN&SA = X&EI = noUaUJKpLcem0QXHsYC4Cw&redir_esc = Y#v = onepage&q =%22%20To%20avoid%第二十条%20captured%20variable%20trap%22&F =假 – 2012-08-02 13:51:09