Доброго времени суток!У меня есть задача - принимать пайпом в перл-скрипт лог апача (по другому никак) и там уже производить некие операции.
Написал скрипт, который принимает в один поток - работает, но много процессов апача висят в состоянии L (Logging) - нагрузка очень тяжелая.
Я сделал вывод, что читать из пайпа нужно в несколько потоков. И тут появились грабли.
Делаю примерно следующим образом по аналогии с обычным префорковым аццептом (много кода упущено для простоты):
=================================
# Ловим сигналы
$SIG{TERM} = sub { $please_die = 1; };
$SIG{INT} = sub { $please_die = 1; };
$SIG{CHLD} = \&terminator;
$SIG{PIPE} = sub { $please_die = 1; };
# Префорковый цикл родителя
PARENT: while (1) {
&killall if ($please_die);
if (scalar(keys %children) < $children) {
my $pid = fork;
die "$0: fork failed: $!\n" unless defined $pid;
last PARENT if $pid == 0;
$children{$pid} = 1;
}
select(undef, undef, undef, 0.1);
&killall if ($please_die);
}
# Здесь инициализируются потомки
$SIG{TERM} = sub { exit; };
$SIG{PIPE} = sub { exit; };
$SIG{INT} = sub { exit; };
# Собственно, МНОГО потомков читают один и тот же пайп
while (<>) {
if (/^(\d+\.\d+\.\d+\.\d+) ([a-zA-Z0-9_\-.]+) \[([^\]]+)\] "[a-zA-Z]+ ([^"]+) HTTP\/\d\.\d" (\d+) (\d+|\-) "([^"]*)" "([^"]*)"/) {
if ($itr++ > $maxperchild) {
exit;
}
# Здесь анализируем прочитанную строку
}
}
=================================
Я так понимаю, чтение из STDIN существенно отличается от accept() :) И по этому читать надо как то по другому, ибо все дико глючит.
Вопрос. Как правильно передавать потомкам родительский STDIN, чтобы один из потомков его читал по мере того как освободится?