2011-10-20 42 views
1

下面的代碼處理一個帶有2個參數的套接字消息。它將信息放入隊列並在另一個線程上處理。我的問題是,如果2個消息正好在另一個之後進入,然後出隊併發送到方法ProcessData,那麼ProcessData上是否存在爭用條件?隊列上的爭用條件

private void DataIn(long Code, string Message) 
{ 
    if (!Started) 
    { 
    if (DataInQueue == null) 
     DataInQueue = new Queue(); 
    DataInThread = new Thread(new ThreadStart(ThreadProcedure)); 
    DataInThreadEnding = false; 
    DataInThread.IsBackground = true; 
    DataInThread.Start(); 
    Started = true; 
    } 
    DataInQueue.Enqueue(new cDataIn(Code, Message)); 
} 

private void ThreadProcedure() 
{ 
    while (!ProgramEnding) 
    { 
    Queue mySyncdQ = Queue.Synchronized(DataInQueue); 
    if (mySyncdQ != null && mySyncdQ.Count > 0) 
    { 
     cDataIn data = null; 
     // Creates a synchronized wrapper around the Queue. 
     if (mySyncdQ.Count > 0) 
      data = (cDataIn)mySyncdQ.Dequeue(); 

     ProcessData(data); 
    } 
    } 

} 

回答

5

UPDATE

隊列不是一個線程安全的方式在你的代碼中使用...您展示這些代碼是不夠的,以確保是否有競爭狀態,但隨着ConcurrentQueue你更好的性能......並且在ThreadProcedure中,您可以使用null調用ProcessData,並且據我所知可以放在安全的一面ProcessData應該是可重入的以便所有這些工作...

使用ConcurrentQueue - 這避免了一些可能的問題......並檢查出BlockingCollection這是專爲線程安全生產者/消費者的情況下...都工作大部分無鎖和非常快...

+0

你是說有問題嗎? – Jon

+1

Queue類的文檔(http://msdn.microsoft.com/zh-cn/library/system.collections.queue(v=VS.100).aspx)有一個關於線程安全的段落,實例成員不是TS。我沒有看過執行情況,看看有什麼變化,但你可以通過旋轉兩個線程來檢查自己。一個在順序消息中泵(1,2,3 ...),另一個讀取它們。你可能會得到一個例外或差距/雙打(1,2,2,4,5,...)。 – gjvdkamp

+0

請參閱我上面的更新... – Yahia

4

是的我認爲這甚至可以讓您的隊列處於不穩定的狀態。您應該使用.Net 4附帶的Concurrent QueueBlockingCollection。它是開箱即用的優化線程。

關注Gert-Jan

+0

http://blog.mischel.com/2011/03/22/memory-leak-in-concurrentqueue/ – Jon

+0

爲什麼你說隊列有問題?我更擔心ProcessData被連續調用,第二個線程可能會超過第一個 – Jon

+0

@Jon,內存泄漏很可能不會影響到您。 – svick

3

您的代碼不是線程安全的。在the documentation for Queue.Synchronized()注意這一點:

爲了保證Queue的線程安全的,所有的操作都必須通過僅此包裝來完成。

您直接使用隊列,因此代碼不是線程安全的。爲了解決這個問題,總是使用返回的包裝,正如文檔所述。

或者,如果您使用.Net 4,請使用ConcurrentQueue<T>

如果您想要在先前版本的.Net上使用通用隊列,您可以使用Queue<T>並始終通過lock訪問它。

+0

所以我需要調用同步當我入隊和出隊? – Jon

+0

這就是文檔所說的,不是嗎? – svick

+0

實際上並沒有說入隊和出隊 – Jon