繁体   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