tags:

views:

93

answers:

2

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: http://groups.google.com/group/comp.soft-sys.matlab/browse_thread/thread/eb4ebeb8700ea440/13bd6710e8429a70?lnk=raot

http://www.mathworks.com/matlabcentral/newsreader/view_thread/279510

A: 

Write to a new file, then rename it. Renaming is an atomic operation, and all the new content will become visible at once.

Ben Voigt
This idea was proposed also in http://groups.google.com/group/comp.soft-sys.matlab/browse_thread/thread/eb4ebeb8700ea440/13bd6710e8429a70?lnk=raotbut it turns out that unix's rename is not atomic (first it deletes the dest file, then source file renamed), and matlab uses unix's rename in unix,so this solution does not work neither.
David Portabella
Just read that thread. The consensus seems to be that MatLab's `movefile` command does more than just a single `rename` call, so `movefile` isn't atomic. The SUS is pretty clear that `rename` is atomic on unix (of course, if you're using a Unix-like clone that doesn't adhere to the spec that's a different story). http://opengroup.org/onlinepubs/007908775/xsh/rename.html
Ben Voigt
A: 

At the end I did one implementation based on two consecutive tests (movefile, and verify the contents of the moved file).

not very well written, but it works for now for me.

+++++ file_lock.m ++++++++++++++++++++++++

function file_lock(op, filename)
%this will block until it creates the lock file:
%file_lock('create', 'mylockfile') 
%
%this will remove the lock file:
%file_lock('remove', 'mylockfile')


% todo: verify that there are no bugs

filename = [filename '.mat'];

if isequal(op, 'create')
  id = [tempname() '.mat'] 
  while true
    save(id, 'id');
    success = fileattrib(id, '-w');
    if success == 0; error('fileattrib'); end

    while true
      if exist(filename, 'file');        %first test
        fprintf('file lock exists(1). waiting...\n');
        pause(1); 
        continue;
      end
      status = movefile(id, filename);   %second test
      if status == 1; break; end
      fprintf('file lock exists(2). waiting...\n');
      pause(1);
    end

    temp = load(filename, 'id');         % third test.
    if isequal(id, temp.id); break; end

    fprintf('file lock exists(3). waiting...\n');
    pause(1)
  end

elseif isequal(op, 'remove')
  %delete(filename);
  execute_rs(@() delete(filename));

else
  error('invalid op');
end



function execute_rs(f)
while true
  try 
    lastwarn('');
    f();
    if ~isequal(lastwarn, ''); error(lastwarn); end  %such as: Warning: File not found or permission denied 
    break;
  catch exception
    fprintf('Error: %s\n.Retrying...\n', exception.message);
    pause(.5);
  end
end

++++++++++++++++++++++++++++++++++++++++++

David Portabella
I think you have a problem if a worker is interrupted right before `movefile`.
Ben Voigt

related questions