How to Lock/Unlock a File Across Process

How to lock/unlock a file across process?

Get help from mono mail list "http://mono.1490590.n4.nabble.com/File-Locking-td4663839.html"

below is the answer quote from "Edward Ned Harvey (mono)"

Kinda sorta. The underlying issue is that OSX, Linux, and Windows all
have different underlying file locking constructs, and then of course,
there's some variability about even which filesystem is being used.
I didn't thoroughly figure out all the answers for every OS or
filesystem, and I don't know under which situations this will be good
enough, but this is what I ended up using, works under the conditions
we needed it to work:

using (var foo = new FileStream(filePath, FileMode.Open,FileAccess.ReadWrite, FileShare.None)) { // must include Write access in order to lock file 
foo.Lock(0, 0); // 0,0 has special meaning to lock entire file regardless of length
}

For windows, simply specifying the FileAccess and FileShare is good
enough. For linux, at least ext4, files are concurrently readable
regardless of what you specify for FileAccess and FileShare. The
Lock() method does something of a soft-lock. It's not enforced by the
OS, but at least all the situations we tried, other client apps honor
the lock. Didn't look into it any deeper.

how to lock a file so that other process cannot cat it?

File locking is not mandatory locking — it is advisory locking.

That means that if a program such as cat does not look to see whether a file is locked, it doesn't matter whether some other program locks it or not — cat will still read the file.

Unless you use a variant of cat that does check for file locks, you are not going to be able to use file locking to stop cat.

What can you do instead?

  1. Rename the file.
  2. Change permissions on the file.
  3. Decide not to worry about it.

The last option is the easiest — and probably most effective.

Some systems do support mandatory file locking. Typically, that's indicated by setting the SGID bit on a non-executable file. If you're using such a system, then you should be able to prevent cat from working on a locked file.

Python locking and unlocking file from multiple processes

  1. Ok first, locking a file is a platform-specific operation, so you will need to run different code for different operating systems.
  2. Secondly, as @Kevin said here, - "coordinating access to a single file at the OS level is fraught with all kinds of issues that you probably don't want to solve. Your best bet is have a separate process that coordinates read/write access to that file."

Locking files. What to do first? Unlock or close?

As long as you don't write(2) to a file (after the unlocking), it does not matter if you unlock it first or close(2) it first.

However, close(2)-ing a file would unlock it (at least if no other process share the same opened file descriptor).

See fcntl(2) which says

As well as being removed by an explicit F_UNLCK, record locks are
automatically released when the process terminates or if it closes any
file descriptor referring to a file on which locks are held.

addenda: should check for failures

Notice that your code is missing error checking. Almost every library function or syscall, in particular fcntl, read, write, could fail (and set errno to be displayed by e.g. perror or strerror(errno) in some log or print). You don't check the success or failure of fcntl in your LockFile or UnlockFile functions, and you don't check neither in the caller.

Is there a way to share a lock (e.g. a lock file) between R processes?

While I couldn't find an R package, there is the Linux command lockfile that can be used:

write("Attempting to get lock", stderr())
system("lockfile /tmp/my_simple_lock")

# Do stuff

write("Releasing lock", stderr())
system("rm -f /tmp/my_simple_lock")

proper way to use lock file(s) as locks between multiple processes

On Unices the traditional way of doing pure filesystem based locking is to use dedicated lockfiles with mkdir() and rmdir(), which can be created and removed atomically via single system calls. You avoid races by never explicitly testing for the existence of the lock --- instead you always try to take the lock. So:

lock:
while mkdir(lockfile) fails
sleep

unlock:
rmdir(lockfile)

I believe this even works over NFS (which usually sucks for this sort of thing).

However, you probably also want to look into proper file locking, which is loads better; I use F_SETLK/F_UNLCK fcntl locks for this on Linux (note that these are different from flock locks, despite the name of the structure). This allows you to properly block until the lock is released. These locks also get automatically released if the app dies, which is usually a good thing. Plus, these will let you lock your shared file directly without having to have a separate lockfile. This, too, work on NFS.

Windows has very similar file locking functions, and it also has easy to use global named semaphores that are very convenient for synchronisation between processes.

How can I lock a file using java (if possible)

FileChannel.lock is probably what you want.

try (
FileInputStream in = new FileInputStream(file);
java.nio.channels.FileLock lock = in.getChannel().lock();
Reader reader = new InputStreamReader(in, charset)
) {
...
}

(Disclaimer: Code not compiled and certainly not tested.)

Note the section entitled "platform dependencies" in the API doc for FileLock.



Related Topics



Leave a reply



Submit