Гостевая книга admin
Гостевая книга admin
Гостевая книга admin

Registration

Forgot password

 

 Main Page


 Фотогалерея


Создать гостевую книгу


Скачать скрипт гостевой-форума


Документация

  • Как работает fork

  • Как работает exec

  • Как работает system

  • Бильярд. Flash игра.

  • Что такое Ajax и как он используется в Гостевых книгах Firebook

  • Скрипт Форума

  • Perl code of Module Firebook



     Google

     Webmoney

     Сайт разработчика

     Скрипт гостевой


  • Perl 10 июн 2008 (4:15) Как работает fork

    Функция fork() в perl создает параллельный процесс в памяти системы, который отличается от родительского лишь своим идентификатором ($$). Все остальные права и полномочия, как будет показано ниже, наследуются.

    Пример:

    [code]

    #!/usr/bin/perl

    # Как работает fork()

    $|=1; # запрещаем буферизацию вывода

           # Если этого не сделать, то при параллельной работе двух процессов

           # в браузер будет не все выводиться

    print "Content-type: text/html; charset=windows-1251\n\n";

    print "<p>Привет\n";

    my $parent=$$; # Зафиксируем свои родительские права

                # $$ - идентификатор процесса

    print "<p>I am parent $parent\n";

    my $child=fork(); # Порождаем потомка

                # Далее параллельно работают две программы

                # отличия только в идентификаторе процесса $$

    # Можно записать так:                        

    # if($child=fork()){выполняется родитель}elsif(undef $child){выполняется потомок}else{die "функция fork не сработала"}      

    # потомок не может породить своего потомка и этим можно пользоваться      

    print "<p>pid=$child\n"; # если работает потомок, то $child=0

    if($$ == $parent){

    # выполняется родитель

          print "<p>Parent: pid=$$;($parent)\n";

    }else{

    # выполняется потомок

          print "<p>Child: pid=$$;(my parent $parent)\n"; # Потомок знает своего родителя

          # Запускаем для хохмы потомка в бесконечном цикле

          # Контролировать его будет родитель

          while(100){

          sleep(1); # каждую секунду показываем его работу

          my $t=time();

                print "<p>Child (pid=$$): $t\n";

                $N++;if($N>20){last} # выход для страховки

          }

    }

    # Но родитель не дремлет, параллельно работает и следит за потомком

    my $t0=time();

    while(time() <$t0+10){

          sleep(5);

          print "<p>The parent does not sleep\n";

          

    }

    # 10 секунд прошло, можно убивать потомка

    if(kill(0,$child)){ # проверим, может быть он уже сам накрылся (сисадмин его прибил с консоли)

    # если жив, убиваем. А то ведь, в бесконечном цикле работает

          my $kill=kill_my($child);

          print "<p>kill=$kill; pid=$$; child=$child\n";

    };

    print "<p>I am parent=$parent\n<p>The end\n";

    if($^O =~/Win/ && !exists($ENV{REMOTE_ADDR})){<>}; # проверим работу проги с консоли

    exit;

    sub kill_my{

    my ($id)=@_;      

    my $syst=$^O;

    # посылаем сигнал TERM системе на ликвидацию процесса $id

    # В windows сигналов нет, но зато есть эмуляция некоторых сигналов

    if($syst =~/Win/){return kill(9,$id)}else{return kill("TERM",$id)};

    }

    [/code]

    Результат работы скрипта

    [code]

    Привет

    I am parent 14345

    pid=0

    Child: pid=14346;(my parent 14345)

    pid=14346

    Parent: pid=14345;(14345)

    Child (pid=14346): 1213073844

    Child (pid=14346): 1213073845

    Child (pid=14346): 1213073846

    Child (pid=14346): 1213073847

    The parent does not sleep

    Child (pid=14346): 1213073848

    Child (pid=14346): 1213073849

    Child (pid=14346): 1213073850

    Child (pid=14346): 1213073851

    Child (pid=14346): 1213073852

    The parent does not sleep

    kill=1; pid=14345; child=14346

    I am parent=14345

    The end

    [/code]

    При написании игрового сервера, этот пример может вам пригодиться.


    Дополнение 1

    Все-таки страховка в бесконечном дочернем цикле оказалась не лишней

    $N++;if($N>20){last}

    Дело в том, что со смертью (преждевременной) родительского процесса, дочерний процесс продолжает работать.

    [code]

    if($$ == $parent){

    # выполняется родитель

          print "<p>Parent: pid=$$;($parent)\n";

    # В блок внесены изменения

          print "<p>Parrent is killed\n";

          kill_my($parent); #добавил. родитель убивает сам себя

    print "<p>Parent is died\n"; # этой сточки мы не должны увидеть, потому что родитель уже мертв

          exit; # и для надежности exit

    }else{

    # Выполняется потомок

    [/code]

    Результат работы с убитым родителем

    [code]

    Привет

    I am parent 4025

    pid=4026

    Parent: pid=4025;(4025)

    Parent is killed

    pid=0

    Child: pid=4026;(my parent 4025)

    Child (pid=4026): 1213080644

    Child (pid=4026): 1213080645

    Child (pid=4026): 1213080646

    Child (pid=4026): 1213080647

    Child (pid=4026): 1213080648

    Child (pid=4026): 1213080649

    Child (pid=4026): 1213080650

    Child (pid=4026): 1213080651

    Child (pid=4026): 1213080652

    Child (pid=4026): 1213080653

    Child (pid=4026): 1213080654

    Child (pid=4026): 1213080655

    Child (pid=4026): 1213080656

    Child (pid=4026): 1213080657

    Child (pid=4026): 1213080658

    Child (pid=4026): 1213080659

    Child (pid=4026): 1213080660

    Child (pid=4026): 1213080661

    Child (pid=4026): 1213080662

    Child (pid=4026): 1213080663

    Child (pid=4026): 1213080664

    N=21;Last

    The parent does not sleep (4026)

    [/code]

    Последнюю строчку выдал не родитель, а потомок, благополучно завершивший цикл по страховке. Если бы не страховка, то остановить его смог бы только сисадмин, который заодно и оплуху тебе влепил бы за разбазаривание системных ресурсов. Во как!

    дополнение 2

    Проверим, можно ли из дочернего процесса убить родителя.

    Вносим измнения в код

    [code]

    # выполняется потомок

          print "<p>Child: pid=$$;(my parent $parent)\n"; # Потомок знает своего родителя

          # Запускаем для хохмы потомка в бесконечном цикле

          # Контролировать его будет родитель

    my $kill=kill_my($parent); # потомок убивает родителя

          print "<p>Parent is killed ($kill)\n";

    while(1){

          sleep(1);

    ....

    [/code]

    Результат

    [code]

    Привет

    I am parent 23678

    pid=23679

    Parent: pid=23678;(23678)

    pid=0

    Child: pid=23679;(my parent 23678)

    Parent is killed (1)

    Child (pid=23679): 1213081467

    Child (pid=23679): 1213081468

    ....

    Child (pid=23679): 1213081469

    Child (pid=23679): 1213081487

    N=21;Last

    The parent does not sleep (23679)

    [/code]

    Потомок убивает родителя и спокойно работает дальше.

    Ну дела...

    Кстати, если то же самое запустить в винде, то там со смертью родительского процесса, умирают и все дочерние. По-моему, я где-то читал, что так и должно быть. А на реальном Unix-сервере процессы живут независимо друг от друга. М-да.

    Дополнение 3

    Проверим, можно ли из дочернего процесса создать новый дочерний процесс.

    Вносим изменения в код

    [code]

    }else{

    # выполняется потомок

          print "<p>Child: pid=$$;(my parent $parent)\n"; # Потомок знает своего родителя

          # Запускаем для хохмы потомка в бесконечном цикле

          # Контролировать его будет родитель

          my $kill=kill_my($parent); # убиваем родителя

          print "<p>Parent:$parent is killed ($kill)\n";

          my $new_pid=fork(); # создаем нового потомка

          print "<p>The child:$$ born child ($new_pid)\n"; # показываем его идентификатор

          while(1){

          sleep(1); # каждые 2 секунды показываем его работу

          my $t=time();

                print "<p>Child (pid=$$): $t\n";

                $N++;if($N>20){print "<p>N=$N;Last\n";last}

          }

    }

    [/code]

    Результат

    [code]

    Привет

    I am parent 22349

    pid=22351

    pid=0

    Parent: pid=22349;(22349)

    Child: pid=22351;(my parent 22349)

    Parent:22349 is killed (1) - родитель УБИТ

    The child:22351 born child (22352) - потомок 22351 создает потомка 22352

    The child:22352 born child (0) - а этот потомок-внук не может создать нового

    Дело в том, что он не может создать нового только в тот момент, когда его самого только что создали. Но в новом fork-е он вполне успешно сделает это.

    Child (pid=22351): 1213085644

    Child (pid=22352): 1213085644

    Child (pid=22351): 1213085645

    Child (pid=22352): 1213085645

    Child (pid=22351): 1213085646

    Child (pid=22352): 1213085646

    Child (pid=22351): 1213085647

    .. Сын и внук вполне нормально существуют оба при мертвом дедушке

    Child (pid=22352): 1213085664

    Child (pid=22351): 1213085665

    Child (pid=22352): 1213085665

    N=21;Last:22351 - по страховке завершился сын

    N=21;Last:22352 - по страховке завершился внук

    The parent does not sleep (22351)

    The parent does not sleep (22352)

    [/code]

    Такие вот дела... Эдак можно плодить потомков из потомков до бесконечности...


    Резюме

    Все порожденные процессы могут создавать новые процессы до бесконечности.

    Смерть родителя никак не влияет на жизнеспособность потомка.

    К примеру такой цикл может обрушить сервер

    [code]

    while(1){

    # на практике не пробовал и вам не советую

    slip(1);

    fork();

    }

    [/code]

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

    В общем, все надо попробовать самому, иначе жизнь будет пресной и скучной.


    Комментарии

    Мои гости

     

    Perl
    1.На сайте narod.ru невозможно разместить нашу
    2.Программирование это, кроме всего прочего, очень
    3.Я поправил алгоритм. Теперь и при
    4.Я отправил письмо на ваш адрес.
    5.Господа, вынужден еще раз подчеркнуть, что
    6.Посмотрите в папке spam. Возможно rambler
    7.Защита от спама
    8.С праздником, дорогие женщины!
    9.Поражаюсь упорству некоторых. Постят ссылки, и
    10.Да мне в принципе не жалко,
    11.Занятная игрушка
    12.Когда ты в режиме Админа (в
    13.Спасибо за тестирование. Я попытаюсь найти
    14.Иди в свою книгу, там поговорим.
    15.Такое бывает тогда, когда человек пытается
    16.Проверил. Вроде бы все работает. #23
    17.Почистил ресурс. Все заброшенные своими хозяевами
    18.Фотогалерея:
    20.Данные сервера посылаются только Админу и


     0 >>   end(140)


    open/close

    Имя:

    Email: Hpage:

    Тема:

     

    Service:

    Вставить цитату  image link bold code

    Smiles:                        Все смайлы

    Введите код:

    New message

    Вернуться в Гостевую

    Примечание:

    click close form
    :FB1337540305

    Рейтинг@Mail.ru ©Guestbook