问题
I have an application which constantly (+-100ms) reads orders from a PLC and then puts them in a model which then gets read by multiple clients. For this im using the lock statement.
Order Reading thread :
lock (model) {
//update object
}
Clients Reading :
lock (model) {
//serialize object to json string
}
send over tcp stream to client.
But i could also use for the update :
Interlocked.ExChange(oldObj, newObj)
I don't want my clients to have to wait for a lock that is happening in the Order Reading thread. And i definitly dont want client to block my Order Reading thread.
Am i better off using the Interlocked ?
Thanks for the advice!
回答1:
Yes, you are better off using Interlocked
as it's more efficient since it's mostly translated into a single atomic operation.
However, if you don't mind the clients still reading the old object for a bit you can even do without the Interlocked and just set a new instance.
The client that happen to get the new instance will get the updated data and those that don't will get it in one of the next checks.
回答2:
If your single producer is creating a brand new model, and assigning it to a shared field, then yes, Interlocked.Exchange
is the way to go here.
If your producer does not need to know what the old model was, then you could use Volatile.Write(ref _sharedObj, newObj)
instead to keep it simpler.
Just be aware of 3 things:
- Use
Volatile.Read
to read your shared object. The consumers should read the shared state once per unit of work
//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);
The consumers will sometimes be using a slightly outdated model. So be sure that using a slightly outdated object doesn't cause you any trouble
var obj = _sharedObj; // If _sharedObj is exchanged here, then `obj` will be outdated var x = CalculateX(obj); var y = CalculateY(obj);
来源:https://stackoverflow.com/questions/32121684/lock-vs-interlocked-exchange