Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

atomically creating a file lock in MATLAB (file mutex)

I am looking for a simple already implemented solution for atomically creating a file lock in MATLAB.

Something like:

file_lock('create', 'mylockfile'); %this will block until it creates the lock file.
file_lock('remove', 'mylockfile'); %this will remove the lock file:

This question has already been asked several times, with some proposed solution ideas (such as using Java FileLock), but I didn't find a simple already implemented solution.

Are you aware of such an implemented solution?

Notes:

  • locking file access OR exchanging messages bw Matlab Instances
  • Thread Subject: Safe file mutex without race condition
like image 360
David Portabella Avatar asked Aug 10 '10 16:08

David Portabella


3 Answers

I've settled on a pretty simple solution for combining error/logging messages from multiple worker threads into a single file. Every time I want to write to that file, I first write the output to the thread's own temporary file. Next, I append that temporary file to the "master" log file using flock. Skipping over some details here, the idea is:

fid=fopen(threadtemp, 'w');
fprintf(fid, 'Error message goes here');
fclose(fid);

runme = sprintf('flock -x %s -c ''cat %s >> %s''', LOGFILE, threadtemp, LOGFILE);
system(runme);

See the flock man page for details, but the call above is acquiring an eXclusive lock on the logfile, running the provided Command under the lock, and then releasing it.

This obviously only works if you're on a system which has flock (Linux/OS X, and only certain types of file systems at that) and you're doing something that can be done from the command line, but I'd bet that it's a pretty common use-case.

like image 101
Matt Krause Avatar answered Nov 19 '22 13:11

Matt Krause


Depending on which Java version you're using, perhaps this will work (translated from: http://www.javabeat.net/2007/10/locking-files-using-java/)

classdef FileLock < handle
    properties (Access = private)
        fileLock = []
        file
    end

    methods
        function this = FileLock(filename)
            this.file = java.io.RandomAccessFile(filename,'rw');
            fileChannel = this.file.getChannel();
            this.fileLock = fileChannel.tryLock();
        end

        function val = hasLock(this)
            if ~isempty(this.fileLock) && this.fileLock.isValid()
                val = true;
            else
                val = false;
            end
        end

        function delete(this)
            this.release();
        end

        function release(this)
            if this.hasLock
                this.fileLock.release();
            end
            this.file.close
        end
    end
end

Usage would be:

lock = FileLock('my_lock_file');
if lock.hasLock
    %// do something here
else
    %// I guess not
end
%// Manually release the lock, or just delete (or let matlab clean it up)

I like the obj wrapping pattern for IO so that releasing happens even in exceptions

EDIT: The file ref must be kept around and manually closed or you won't be able to edit this. That means this code is only really useful for pure lock files, I think.

like image 41
Nathan Donnellan Avatar answered Nov 19 '22 14:11

Nathan Donnellan


If you only need to run on OS X and Linux (not Windows), you can use the following:

pathLock='/tmp/test.lock'

% Try to create and lock this file.
% In my case I use -r 0 to avoid retrying
% You could use -r -1 to retry forever, or for a particular amount of time,
% etc, see `man lockfile` for details.
if ~system(sprintf('lockfile -r 0 %s',pathLock))
    % We succeeded, so perform some task which needs to be serialized.
    % runSerializedTask()
    % Now remove the lockfile
    system(sprintf('rm -f %s',pathLock));
end
like image 1
nonagon Avatar answered Nov 19 '22 15:11

nonagon