2013-07-31 233 views
2

約一次訪問從多個線程局部變量的幾個問題:C#變量線程安全

  1. 我有多個線程寫入和讀出一個變量的值,我應該同步訪問它呢?

  2. 該變量每隔幾秒從Thread1更新一次,並且它每隔幾秒從Thread2讀取並更新到數據庫。

  3. 如果我不保留任何邏輯並且沒有任何併發​​問題,會發生哪些問題?

  4. 我應該使用volatile嗎?

編輯:

我想強調的是,我沒有任何併發​​問題。這是我的具體情況:

a。我的變量的名稱是pingLatency,它測量ping延遲

b。 Thread1發送一個ping到8.8.8.8每10秒,並寫入延遲到pingLatency

c。線程2每10秒更新一個值爲pingLatency的校正字段。 d)。線程2每次更新同一個數據庫行。

現在,我正在使用此數據庫字段來監視網絡連接。我的問題是 - 可能會出現這樣的情況:變量未更新,或者由於線程安全問題而會拋出異常?我想避免使用lock,因爲它看起來像是一種矯枉過正。

您認爲如何?

+1

答案:1。 2.這取決於; 3.很多; 4:可能。您是否嘗試過搜索[so]以解決討論此問題的現有問題?這裏有很多關於線程安全的問題。 –

+0

你的意思是「局部變量」究竟是什麼?發表一個例子。 –

+0

我假設當你說*變量*你實際上是指*字段*,因爲一個*變量*總是*本地*,然後你將無法從多個線程訪問它。 –

回答

2
  1. 是的,你應該有methods to do this for you without locks
  2. 無可奉告
  3. 沒有你所說的這個東西肯定......最有可能到頭來你會插入同步訪問它,如果它是一個基本類型將錯誤值寫入數據庫
  4. Don't use volatile, per Eric Lippert,它過於複雜,語義非常奇怪。

要小心打破內存模型,C#大大的遵循大多數其他語言的使用順序一致性的數據免賽程序(SC-DRF)。易失性打破了這一點,所以只需使用鎖來防止數據競爭。

至於lock這不像人們想象的那麼沉重,在大多數情況下,鎖定不會在您想象的情況下發生爭用。因此在大多數情況下獲得鎖應該是無痛的。

+0

埃裏克並沒有說你不應該使用volatile,他說它可能不符合你的想法確實。如果你知道它是什麼意思,那麼'volatile'是完全合適的。 –

+0

@ LasseV.Karlsen鑑於文檔中提到的與Eric不同,我將避免使用volatile,因爲這意味着即使MS不確定volatile是什麼意思。另外埃裏克非常清楚,「volatile」會破壞SC-DRF。 – Mgetz

+1

揮發性確實意味着原子,因爲只有原子場可能是揮發性的。 –

0

如果您希望.NET託管並行使用內置的好東西。 Task Parallelism。這將爲您管理線程,您可以使用內置的線程安全變量,就像數組/列表等於ConcurrentBag等一樣。

0

如果對您的變量的訪問是原子性的,並且沒有邏輯問題你還行。 根據this你可以知道你是否正在使用一個原子變量。

+1

這是假設他知道諸如內存圍欄,易失性字段的使用等等。 –