簡體   English   中英

鎖定與互鎖

[英]lock vs Interlocked.Exchange

我有一個應用程序,該應用程序不斷(+ -100ms)從PLC讀取訂單,然后將它們放入模型中,然后由多個客戶端讀取。 為此,我使用了lock語句。

訂單閱讀線程:

lock (model) {
//update object
}

客戶閱讀:

lock (model) {
//serialize object to json string
}
send over tcp stream to client.

但我也可以使用更新:

Interlocked.ExChange(oldObj, newObj)

我不希望我的客戶必須等待訂單讀取線程中發生的鎖定。 而且我絕對不希望客戶阻止我的訂單閱讀線程。

我最好使用互鎖嗎?

謝謝你的建議!

是的,您最好使用Interlocked因為它效率更高,因為它通常已轉換為單個原子操作。

但是,如果您不介意客戶端仍在閱讀舊對象,甚至可以在沒有互鎖的情況下進行操作,而只需設置一個新實例即可。

碰巧獲得新實例的客戶端將獲得更新的數據,而沒有碰到的客戶端將在接下來的檢查之一中獲取它。

如果您的單個生產者正在創建一個全新的模型,並將其分配給共享字段,那么可以, Interlocked.Exchange是解決之道。

如果生產者不需要知道模型是什么,則可以使用Volatile.Write(ref _sharedObj, newObj)使其更簡單。

請注意以下三點:

  1. 使用Volatile.Read讀取共享對象。
  2. 消費者應每個工作單元讀取一次共享狀態

     //incorrect - _sharedObj is not guaranteed to be the same in both reads var x = CalculateX(_sharedObj); var y = CalculateY(_sharedObj); //correct var obj = Volatile.Read(ref _sharedObj); var x = CalculateX(obj); var y = CalculateY(obj); 
  3. 消費者有時會使用稍微過時的模型。 因此,請確保使用稍微過時的對象不會給您帶來任何麻煩

     var obj = _sharedObj; // If _sharedObj is exchanged here, then `obj` will be outdated var x = CalculateX(obj); var y = CalculateY(obj); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM