C++ how to check if file is in use - multi-threaded multi-process system
-
30-04-2021 - |
Question
C++: Is there a way to check if a file has been opened for writing by another process/ class/ device ?
I am trying to read files from a folder that may be accessed by other processes for writing. If I read a file that is simultaneously being written on, both the read and the write process give me errors (the writing is incomplete, I might only get a header). So I must check for some type of condition before I decide whether to open that specific file. I have been using boost::filesystem to get my file list. I want compatibility with both Unix and Windows.
Solution
You must use a file advisory lock. In Unix, this is flock
, in Windows it is LockFile
.
However, the fact that your reading process is erroring probably indicates that you have not opened the file in read-only mode in that process. You must specify the correct flags for read-only access or from the OS' perspective you have two writers.
Both operating systems support reader-writer locks, where unlimited readers are allowed, but only in the absence of writers, and only at most one writer at a time will have access.
Since you say your system is multi-process (ie, not multi thread), you can't use a condition variable (unless it's in interprocess shared memory). You also can't use a single writer as a coordinator unless you're willing to shuttle your data there via sockets or shared memory.
OTHER TIPS
From what I understand about boost::filesystem
, you're not going to get the granularity you need from that feature-set in order to perform the tasks you're requesting. In general, there are two different approaches you can take:
- Use a synchronization mechanism such as a named semaphore visible at the file-system level
- Use file-locks (i.e.,
fcntl
orflock
on POSIX systems)
Unfortunately both approaches are going to be platform-specific, or at least specific to POSIX vs. Win32.
A very nice solution can be found here using Sutter's active object https://sites.google.com/site/kjellhedstrom2/active-object-with-cpp0x
This is quite advanced but really scaled well on many cores.