атомарное создание блокировки файла в MATLAB (файловый мьютекс) - PullRequest
5 голосов
/ 10 августа 2010

Я ищу простое уже реализованное решение для атомарного создания блокировки файлов в MATLAB.

Что-то вроде:

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

Этот вопрос уже задавался несколько раз, причем некоторыепредлагаемые решения (например, с использованием Java FileLock), но я не нашел простого уже реализованного решения.

Вам известно о таком реализованном решении?

Примечания:

Ответы [ 5 ]

5 голосов
/ 04 ноября 2011

Я остановился на довольно простом решении для объединения сообщений об ошибках / регистрации из нескольких рабочих потоков в один файл. Каждый раз, когда я хочу записать в этот файл, я сначала записываю вывод в собственный временный файл потока. Затем я добавляю этот временный файл в «главный» файл журнала, используя flock. Пропустив некоторые детали здесь, идея:

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);

Для получения подробной информации см. Справочную страницу flock, но приведенный выше вызов получает блокировку eXclusive для файла журнала, выполняет предоставленную Команду под блокировкой и затем освобождает ее.

Это, очевидно, работает только в том случае, если вы работаете в системе, в которой есть flock (Linux / OS X и только некоторые типы файловых систем) и вы делаете что-то, что можно сделать из командной строки, но Держу пари, что это довольно распространенный вариант использования.

1 голос
/ 11 июля 2013

В зависимости от того, какую версию Java вы используете, возможно, это будет работать (в переводе: 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

Использование будет:

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)

Мне нравится объектшаблон обёртки для ввода-вывода, так что освобождение происходит даже в исключительных случаях

РЕДАКТИРОВАТЬ: ссылка на файл должна храниться и закрываться вручную, иначе вы не сможете редактировать это. Это означает, что этот код действительно полезен только для чистогоблокировка файлов, я думаю.

0 голосов
/ 27 октября 2015

Если вам нужно работать только в OS X и Linux (не Windows), вы можете использовать следующее:

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
0 голосов
/ 10 августа 2010

В конце я выполнил одну реализацию, основанную на двух последовательных тестах (movefile, и проверил содержимое перемещенного файла).

не очень хорошо написано, но сейчас оно работает для меня.

+++++ 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

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

0 голосов
/ 10 августа 2010

Запишите новый файл, затем переименуйте его. Переименование является атомарной операцией, и весь новый контент станет видимым сразу.

...