2013-07-02 20 views
3

我有一個Queue<T> _q = new Queue<T>();隊列<T>線程安全:一個作家,一個閱讀器

有永遠只有一個線程填充它:_q.Enqueue(msg);

有永遠只有一個線程消費它:_q.Dequeue();

我想在兩個線程中都是無鎖的。性能是重要的,但安全是第一位的。

我需要製作_q a ConcurrentQueue<T>

UPD 這可能是重要的: 我並不需要確保編寫線程後立刻讀取線程將成功地出列項排入它。如果幾個false出隊將被採取 - 沒關係。

+0

它爲什麼需要無鎖定? ConcurrentQueue使用鎖(你不需要自己處理的鎖),並使用旋轉(我認爲)然後嘗試訪問隊列。 –

+0

你對'ConcurrentQueue'說得對。它使用旋轉,這是一種鎖。但我認爲它比'lock(_q){...}'更好。不使用鎖的主要原因是性能。寫作線程不得在途中遇到某人的鎖。這是一個服務器 – astef

+0

你當然可以建立一個具有這種性能的隊列。只要在「前」索引更新之前將項目插入到單個生產者的隊列存儲中,單個使用者就不能接受錯誤條目。 'Queue'是否有這樣的保證是另一回事。 –

回答

4

,我需要做一個_q ConcurrentQueue

是。隊列不是線程安全的。

+0

重要的是我閱讀它的特殊情況嗎?會發生什麼? – astef

+0

@astef Enqueue和TryDequeue都將改變隊列,所以通常的罪魁禍首競爭條件 - 這是隨機的壞事發生。 – nos

+0

什麼是最糟糕的事情可能發生?某處出現異常?項目錯誤的順序? – astef

3

在這裏您可以找到一個免鎖隊列:Lockfreie threadsichere Queue - 不要害怕德國的網站 - 代碼應該說明問題。此外,還有另一篇更深入的文章Writing Lock-Free Code: A Corrected Queue

+0

你確定比'ConcurrentQueue '更好嗎? – astef

+0

好吧,我並不知道ConcurrentQueue是無鎖的。在這種情況下,我寧願增加另一個框架類。 – JeffRSon

+1

是的,'ConcurrentQueue'不是無鎖的。它使用自旋鎖。 –

0

您也可以使用syncQueue = Queue.Synchronized(_q);,儘管它在內部使用鎖定。

相關問題