We have two threads one for writing and another for removing and one shared directory where one thread creates a new file and writes inside some message, but another scans this directory with a delay and reads the message from the new file and removes it.
So basically I understand that it should be synchronized because if one created the file but has not written yet and another thread takes this empty file and will remove then we will have a problem.
but how long does creating or writing can take time in case if there 4kb for example?
the main question can we avoid synchronization or in this case, synchronization should be?
CodePudding user response:
if one created the file but has not written yet and another thread takes this empty file and will remove then we will have a problem
The solution to this problem is for the file to never be incomplete or invalid.
File creation followed by file population is not an atomic sequence. To make it atomic for readers, the writer should:
- Create a temporary file in the destination directory, e.g.
<filename>~
. So named temporary files (ending with~
) mustn't be read by any other process. When there are multiple competing writers, throw in a combination of (pid
ortid
) and (tsc
ornanoseconds since epoch
) into the temporary filename, e.g.<filename>.<pid>.<nsec>~
. On Linux you can alterantively usemkstemp
to create a unique file for you. - Populate
<filename>~
. - Rename
<filename>~
to<filename>
. On Linuxrenameat2
is an atomic filesystem operation, with optionRENAME_NOREPLACE
it fails when<filename>
already exists, so that multiple writers can detect this condition and act accordingly.std::rename
, unfortunately, doesn't require any particular behaviour when<filename>
already exists.
This way when <filename>
exists it is complete and valid.