I was worried about the state of the race in the application that I am developing when I was interested about this issue.
Say I have a large array or collection of some kind, managed by one component of my program, let this Monitor component. Its task is to regularly check whether the collection is "dirty", i.e. e. has recently changed, and if so, write the snapshot to disk (this will be the reference point of the application in case of failure) and mark it as clean.
Other components of the same program running in a different thread call the Monitor methods to add data or modify data in the array / collection. These methods mark the collection as dirty.
Now change methods are executed in the threads of other components, right? And if I’m not lucky, they can be called while the picture is being written to disk, change the data that has already been written, set the flag dirty, and the Monitor stream will turn off after that without saving the changes (this already passed the element when it changed) . Therefore, I have a dirty collection marked as clean.
For a while, I thought I could solve this problem by creating a temporary copy of the collection, mark it clean, and then go ahead and serialize the copy. But copying will be atomic, i.e. e. can I be sure that the collection will not change while I copy it?
Meanwhile, I think I have found better solutions, for example
- set the lock flag before starting to write to the disk and force the data modification methods to wait until the flag is set
- so that data modification methods are written to the “change queue” instead of directly to the collection and have a stream that processes the process of writing to disk,
and I think a lock flag might be the best way. But I'm still wondering: is it copying an atomic variable?
Follow up . Perhaps this should be connected with the question, but in fact it is very one and the same. According to the answers below, my “flag blocking” approach might not work either, right? Because the data modification method can check the lock flag when it is set to a “locked” value, and decided that it is not locked. So I need a special design, such as a mutex, if I really want to do it right, right?
Kudos to erickson for his very helpful answer on my follow-up. I really had to ask two questions so that I could accept two answers. Please vote it too.