[問題] thread同步問題
各位先進打擾了:
最近在學習 C# 的 thread 使用方法,
目前是參考 msdn 上的 producer / consumer 範例來修改
http://msdn.microsoft.com/zh-tw/library/yy12yx1f(v=VS.80).aspx
以下是我修改後的程式碼:
=========================================================
using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
public class SyncEvents
{
public SyncEvents()
{
_newItemEvent = new AutoResetEvent(false);
_exitThreadEvent = new ManualResetEvent(false);
_eventArray = new WaitHandle[2];
_eventArray[0] = _newItemEvent;
_eventArray[1] = _exitThreadEvent;
}
public EventWaitHandle ExitThreadEvent
{
get { return _exitThreadEvent; }
}
public EventWaitHandle NewItemEvent
{
get { return _newItemEvent; }
}
public WaitHandle[] EventArray
{
get { return _eventArray; }
}
private EventWaitHandle _newItemEvent;
private EventWaitHandle _exitThreadEvent;
private WaitHandle[] _eventArray;
}
public class Producer
{
public Producer(ref Queue<int> q, ref SyncEvents e)
{
_queue = q;
_syncEvents = e;
}
public void ThreadRun()
{
int count = 0;
Random r = new Random();
while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))
//while ((WaitHandle.WaitAny(_syncEvents.EventArray)) != 1)//queue為空
{
lock (((ICollection)_queue).SyncRoot)
{
count++;
_queue.Enqueue(count);
_syncEvents.NewItemEvent.Set();
Thread.Sleep(10);
}
}
Console.WriteLine("Producer thread: produced {0} items", count);
}
private Queue<int> _queue;
private SyncEvents _syncEvents;
}
public class Consumer
{
public Consumer(ref Queue<int> q, ref SyncEvents e)
{
_queue = q;
_syncEvents = e;
}
public void ThreadRun()
{
int count = 0;
while ( (WaitHandle.WaitAny(_syncEvents.EventArray)) != 1)
//while (!_syncEvents.ExitThreadEvent.WaitOne(0, false)) //會當掉
{
lock (((ICollection)_queue).SyncRoot)
{
int item = _queue.Dequeue();
Thread.Sleep(10);
}
count++;
}
Console.WriteLine("Consumer Thread: consumed {0} items", count);
}
private Queue<int> _queue;
private SyncEvents _syncEvents;
}
public class ThreadSyncSample
{
private static void ShowQueueContents(ref Queue<int> q)
{
// 這裡為何只有 look ???
lock (((ICollection)q).SyncRoot)
{
Console.WriteLine("{0} ", q.Count);
}
}
static void Main()
{
// 設定二個要給 thread 用的共用資料結構
Queue<int> queue = new Queue<int>();
SyncEvents syncEvents = new SyncEvents();
// 建構 producer/consumer
Console.WriteLine("Configuring worker threads...");
Producer producer = new Producer(ref queue, ref syncEvents);
Consumer consumer = new Consumer(ref queue, ref syncEvents);
// 令 producer/consumer 的ThreadRun 可在 thread 中運行
Thread producerThread = new Thread(producer.ThreadRun);
Thread consumerThread = new Thread(consumer.ThreadRun);
// 令 二個 thread 中啟動
Console.WriteLine("Launching producer and consumer threads...");
producerThread.Start();
consumerThread.Start();
// 顯示 queue 中的內容
for (int i = 0; i < 4; i++)
{
Thread.Sleep(2500);
ShowQueueContents(ref queue);
}
// 下指令讓 thread 可以離開
Console.WriteLine("Signaling threads to terminate...");
syncEvents.ExitThreadEvent.Set();
// 等待 thread 關閉
producerThread.Join();
consumerThread.Join();
}
}
========================================================
基本上我是希望 producer 產生一個數值放到 queue 並送出一個訊號後,
然後 consumer 則會從 queue 中消除剛才產生的數值,
之後,producer 則會因為收到訊號而再產生一個新數值,
讓 queue 的內容不是放1個就是放0個,
但是這樣改的結果卻是 queue 所存的個數一直在上升中,
是誰發訊號給 producer 呢?不是只有當 consumer 處理完才由 consumer 送出的嗎?
另一個問題則是 while 的功能應該是在判定是否有發出 _exitThreadEvent 嗎?
為何互換後會產生問題呢?
謝謝
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.109.23.55
C_Sharp 近期熱門文章
PTT數位生活區 即時熱門文章