LINUX.ORG.RU

[perl] Неблокирующая запись в файл - возможно?


0

3

Есть 2 скрипта, работающих параллельно. Надо организовать для них примитивный лог вида «$TIMESTAMP $SCRIPTNAME $MESSAGE». Проблема в том, что скрипты представляют собой фактически один процесс (в смысле activity, а не process), поэтому хотелось бы видеть их лог в одном файле. Однако перл (или линукс, что более вероятно) не позволяет получить дескриптор на запись в один файл для двух процессов. Можно ли это как-то обойти простыми способами?

Я вижу только вариант с еще одним скриптом, который через сокет принимал бы сообщения от первых двух и писал в лог сам. Но это слишком большой оверхед, у меня система, критичная ко времени исполнения, которое слишком разрослось и надо бы его уменьшить. т.е. по сути я пытаюсь изобрести примитивный велосип^W профайлер с минимальным влиянием на работающий код

советы будут?

да, готовые профайлеры возможности использовать в силу определенных причин нет

Ответ на: комментарий от Nastishka

не очень понял, как это может мне помочь. или что-то вроде

1.открыть файл

2.разлочить файл

3.залочить->записать->разлочить

?

ибо если разлочить его в обоих скриптах, то можно поиметь проблемы при одновременной попытке записи. я правильно понял?

marvin_yorke ★★★ ()

Однако перл (или линукс, что более вероятно) не позволяет получить дескриптор на запись в один файл для двух процессов.

ещё как позволяет. Простейший вариант-форкнуться, тогда у обоих процессов будет один и тот же дескриптор. Так же есть штатный механизм передачи дескрипторов между процессами, я такое нагугливал. Нужны ли блокировки при этом варианте я не знаю, ман write говорит «The adjustment of the file offset and the write operation are performed as an atomic step.»

true_admin ★★★★★ ()

Однако перл (или линукс, что более вероятно) не позволяет получить дескриптор на запись в один файл для двух процессов.

???

[user@localhost temp]$ cat write2file.pl
#!/usr/bin/perl

open $file, ">>file";
print $file "$$\n";
sleep 10;
close $file;
[user@localhost temp]$ ./write2file.pl & ./write2file.pl
[1] 4949
[1]+  Done                    ./write2file.pl
[user@localhost temp]$ cat file 
4949
4950
[user@localhost temp]$ 

Хотя, конечно же, правильнее использовать блокировки.

Или я вопрос не понял?

hunt ()
Ответ на: комментарий от true_admin

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

isako ★★★ ()

perldoc -f flock

там же есть пример.

arsi ★★★★★ ()
Ответ на: комментарий от hunt

я делаю точно также, но второй инстанс виснет на open. даже open or die не прокатывает. даже после того, как первый умер и закрыл свой дескриптор

marvin_yorke ★★★ ()
Ответ на: комментарий от marvin_yorke

Вообще, нужно смотреть не сколько версию, сколько параметры компиляции перла, но скорее всего это у вас в программе ошибка.

hunt ()

ладно, я сегодня добрый :)

#!/usr/bin/perl

use strict;
use warnings 'all';
use Fcntl qw/:flock SEEK_END/;

open my $log, '>>', 'test.log' or die $!;

for (1..10) {
        flock $log, LOCK_EX or die $!;
        seek $log, 0, SEEK_END or die $!;
        printf $log "%s  [%d]  %d\n", scalar localtime, $$, $_;
        flock $log, LOCK_UN or die $!;
        sleep 1;
}


close $log;
зы: с наступающим ;)

arsi ★★★★★ ()

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

Нормально. Но можно и просто использовать syslog.

Deleted ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.