Как предоставить параллельный доступ для записи к файлу без коллизий?

У меня есть несколько дочерних процессов, которые должны записывать журналы в общий файл. Мне интересно, работает ли этот код, чтобы процессы записывались в общий файл без коллизий:

sub appendLogs {
    open FILE, "+>>", $DMP or die "$!";
    flock FILE, LOCK_EX or die "$!";
    print FILE "xyz\n";
    close FILE;
}

Если нет, не могли бы вы дать мне какие-либо подсказки, как я могу это исправить или улучшить?


person user897237    schedule 15.06.2012    source источник


Ответы (3)


Да, пока каждый процесс, пытающийся записать в файл, использует flock, коллизий не будет.

person Oleg V. Volkov    schedule 15.06.2012
comment
Но что, если мне нужно записать в файл без возможности умереть, если я не могу получить успешный flock? Ваше решение недостаточно хорошо для критических приложений. - person Ωmega; 21.10.2019
comment
@Ωmega, вы не пишете ни одной точки отказа в критических приложениях. И этот вопрос касается логов. - person Oleg V. Volkov; 24.11.2019

Для ведения журнала я бы использовал Log4perl вместо того, чтобы изобретать велосипед. У него есть поддержка того, что вы ищете.

person Bala    schedule 15.06.2012
comment
большое спасибо за отзыв!! ну.. хотя я написал, мне нужен алгоритм для ведения журнала, я... не имею в виду ведение журнала... я должен сохранить какую-то часть файла xml... - person user897237; 15.06.2012

Если вы хотите, чтобы ваш код был переносимым, вам следует перейти к концу файла после того, как вы заблокируете дескриптор файла, но до записи в него. См. пример «дополнения почтового ящика» в perldoc -f flock, который похож на то, что вы делаете.

sub appendLogs {
    open FILE, "+>>", $DMP or die "$!";
    flock FILE, LOCK_EX or die "$!";
    seek FILE, 0, 2;       # <--- after lock, move cursor to end of file
    print FILE "xyz\n";
    close FILE;
}

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

person mob    schedule 15.06.2012
comment
В Linux (или POSIX вообще?) поиск не нужен. Если файл был открыт(2) с помощью O_APPEND, смещение файла сначала устанавливается в конец файла перед записью. Настройка смещения файла и операция записи выполняются как атомарный шаг. - person ikegami; 15.06.2012
comment
@ikegami - достаточно честно. Я переписал свое первое предложение. - person mob; 16.06.2012
comment
Что делать, если смерть после неудачного flock звонка не вариант? - person Ωmega; 21.10.2019