Реферат: Процессы и IPC

Ну это конечно, дюже примитивно. Но если нам нужно только лишь фильтровать, поток вывода, то сойдет. А вот если мы, например, пишем супер-систему обработки ошибок, то этого все-таки маловато. Представим, что этакий сторож фильтрует вывод и сразу отправляет его в настоящий STDOUT. А если возникла фатальная ошибка? Мы выводим сообщение об ошибке, но все это в догонку тому хламу, что уже был отправлен в STDOUT. Такая обработка ошибок, как говорится, "что мертвому припарка". Можно, конечно, накапливать вывод внутри фильтра и выводить только целиком. В случае чего, можно пришибить порожденный процесc с помощью оператора kill. Но увы, поток вывода уже переопределен безвозвратно.

Для решения этой проблемы мы должны кардинально изменить свое мировоззрение. Шучу, конечно. Достаточно вспомнить о таких полезных функциях как select и pipe. Функция select подменяет STDOUT новым дескриптором, а возвращает дескриптор потока вывода, который был актуален на момент до выполнения select, иначе говоря текущий STDOUT. Функция pipe связывает два дескриптора в режиме чтения-записи, то есть создает односторонний канал обмена данными. Отсюда и название – pipe.

Есть очень замечательное свойство систем UNIX - все потоки равны. Прям, коммунизм какой-то. Вот дедушка Ленин бы порадовался. А нам какая с этого польза? Ну как, мы, например, легко можем подсунуть функции select один из дескрипторов, связанных функцией pipe. Естественно, что будем подсовывать тот, который предназначен для записи, иначе я за последствия не ручаюсь. В общем такая незамысловатая программулина

#!/usr/bin/perl –w

# errfilter.pl

my ($fpid,$oldout);

pipe(FOR_READ,FOR_WRITE);

select((select(FOR_READ),$| = 1)[0]);

select((select(FOR_WRITE),$| = 1)[0]);

start_filter();

for ($i = 0; $i < 20; $i ++)

{ print "Output line\n"; }

# Error("bug");

close(FOR_WRITE);

waitpid($fpid,0);

sub start_filter

{

die "Cannot fork" unless defined($fpid = fork);

unless ($fpid == 0)

{

close(FOR_READ);

$oldout = select(FOR_WRITE);

return;

}

close(FOR_WRITE);

my ($out,$num) = ("",0);

while(<FOR_READ>) { $out .= "$num\t$_"; $num ++; }

close(FOR_READ);

print $out;

К-во Просмотров: 630
Бесплатно скачать Реферат: Процессы и IPC