[英]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)
使其更簡單。
請注意以下三點:
Volatile.Read
讀取共享對象。 消費者應每個工作單元讀取一次共享狀態
//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);
消費者有時會使用稍微過時的模型。 因此,請確保使用稍微過時的對象不會給您帶來任何麻煩
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.