私はこのプロデューサー/コンシューマーコードを持っています:
主要 :
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.
そして今 ?両方のスレッドがビジーです!
私は脈が失われることを知っています(またはそうではありませんか?)
唯一の解決策はそれをに変更することAutoResetEvent
ですか?