Автор Тема: ветвление процессов  (Прочитано 3258 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн AnnA

  • Фанатка форума
  • Старожил
  • ****
  • Сообщений: 263
  • +0/-0
  • 2
    • Просмотр профиля
    • http://
ветвление процессов
« : 09 Ноября 2004, 15:56:17 »
Всем приветик.
Умные дяденьки, помогите мне пожалуйста разобраться в этом лесу.
Ну никак что-то я не пойму, что там к чему.
Купила умную книжку, там расписано как использовать модуль Thread и всё бы хорошо, но он даже не установлен у меня такой на хостере к тому же хотелось бы научиться делать ЭТО сначала на fork. :)
Вот написано мол так и так, обязательно дескать используйте:#!/usr/bin/perl -Tw
    use strict;
    [b]use sigtrap;[/b]
    use Socket;
А мне и не жалко. Написано, значит так надо. Написала, делов-то. Только не совсем понятно - зачем? Куда его потом пихать этот $SIG{PIPE} = \'IGNORE\';?
Или я вообще что-то напутала?
Вот у меня есть, например, такая задача: нужно скажем с десяти разных адресов забрать модулем LWP по два-три документа (адреса и имена документов известны). В самом обычном текстовом файле лежат данные по строчкам: адрес, имя документа. Код не нужен - просто сама идея. :)
читаю я файл в массив(он небольшой - 10 строчек всего), а вот теперь самое для меня трудное, - как мне сделать несколько процессов. Т.е. по одному документику в цикле я получаю их все, но это очень уж долго. :(
Просто делаю for для массива, split\'ом достаю адрес, имя документа. Получила, следующий... Примитивно до обидного. :) Ой. Забыла. Сначала я пингую каждый адрес Net::Ping. Если есть пинг - забираю документ, пинга нет - next;
В общем идея такая:foreach (@massiv) {
my ($server,$port,$doca) = split... достаем данные

if ($pid fork) {
 
$p=ping->$server
   
if ($p) { #пинг получен - сервер жив
             #запрашиваем $server:80/$doca при помощи LWP, делаем с ним чего-то;
           
#EO if($p)
             
else {print $server,\'не отвечает\';}
waitpid($pid,0);
    } else {

        die "cannot fork: $!" unless defined $pid;
        exit;

    } #EO if ($pid = fork)

} #EO foreach (@massiv)

ужас, да? :(
Подскажите пожалуйста, как правильно а?
Целое письмо написала.  :)
пока-пока. :)

Оффлайн NeoNox

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3012
  • +0/-0
  • 0
    • Просмотр профиля
ветвление процессов
« Ответ #1 : 09 Ноября 2004, 16:34:23 »
AnnA
1) пинг выносим за пределы форка. незачем нам форкаться а только потом проверять доступность.
2) прироста скорости ты не получишь, потому как в этой схеме ты будешь ждать завершения первого форка, затем второго и так далее.
Идея проста, но не очень красива: форкаться и отдавать управление внешнему(второму скрипту) через exec.
Цитировать
AnnA:
Куда его потом пихать этот $SIG{PIPE} = \'IGNORE\';?

С сигналами нужно вести очень осторожно и использовать их только тогда, когда понимаешь что они должны делать.
В данном случае его пихать никуда не нужно.
The documentations is your friend

Оффлайн AnnA

  • Фанатка форума
  • Старожил
  • ****
  • Сообщений: 263
  • +0/-0
  • 2
    • Просмотр профиля
    • http://
ветвление процессов
« Ответ #2 : 09 Ноября 2004, 16:57:37 »
NeoNox пасиба большое. :)
Цитировать
NeoNox:
пинг выносим за пределы форка.

разве не будет быстрее, если будут пинговаться сразу несколько серверов, а не каждый по очереди?
я так и думала, что вся итерация foreach будет делиться скажем на 5 потоков, т.е. в идеале скрипт должен работать в 2 раза быстрее? нет? А как мне управлять количеством потоков? Где-то надо ставить счетчик, который, например, если ==5, то ждём завершения 1-го потока и вновь идём по кругу с 1-го по 5-й. Т.е. что бы их было не более 5. Или такое невозможно?
Цитировать
NeoNox:
Идея проста, но не очень красива: форкаться и отдавать управление внешнему(второму скрипту) через exec.

ага. :) поняла. спасибо.
А, если красиво (хотя бы просто красиво, а не очень пока) - надо всё таки через Thread делать?
Цитировать
NeoNox:
В данном случае его пихать никуда не нужно.
Хорошо. :) Я тут же забыла про эти сигналы. ;)
пока-пока. :)

Оффлайн NeoNox

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3012
  • +0/-0
  • 0
    • Просмотр профиля
ветвление процессов
« Ответ #3 : 09 Ноября 2004, 18:22:18 »
Цитировать
AnnA:
надо всё таки через Thread делать?

Да. Это будет правильнее.
Цитировать
AnnA:
в идеале скрипт должен работать в 2 раза быстрее? нет?

в идеале да, но не в твоем случае.
напиши на бумажке что, как и когда у тебя происходит в этой программе.
выведи отладку вместе со временем исполнения и ты увидишь о чем я говорю.
The documentations is your friend

Оффлайн AnnA

  • Фанатка форума
  • Старожил
  • ****
  • Сообщений: 263
  • +0/-0
  • 2
    • Просмотр профиля
    • http://
ветвление процессов
« Ответ #4 : 10 Ноября 2004, 15:19:41 »
:confused: Не работает. :insane:
тихохонько так раз. и умирает, и еррор.лог пустенький совершенно вот что обидно. :(
Может вы мне чего-то недоговариваете? :)
Поглядите, если не сложно:open(D,"<","$servers") or die "Can\'t read $servers: $!";
flock(D,LOCK_EX);seek(D,0,0);
while (<
D>) {
my($server,$port)  = split(/:/,$_); chomp($port);
my $p Net::Ping->new();
my $cont $p->ping($server);
    
$p->close();
    if (
$cont)
{ print 
"$server is alive. \\t ";
#-------//BEGIN FORK//-------#
if ($pid fork) { 

#Здесь запросы с помощью LWP

waitpid($pid,0); 
    } else { 

        die 
"cannot fork: $!" unless defined $pid
        exit; 

    } 
#EO if ($pid = fork) 
#-------//END FORK//-------# 

###############################################
 
}
    else {print 
"<font color=red>$server NOT reachible!</font>
"
;}

    } 
#EO while <D>
« Последнее редактирование: 10 Ноября 2004, 15:26:04 от AnnA »
пока-пока. :)

Оффлайн AnnA

  • Фанатка форума
  • Старожил
  • ****
  • Сообщений: 263
  • +0/-0
  • 2
    • Просмотр профиля
    • http://
ветвление процессов
« Ответ #5 : 10 Ноября 2004, 15:22:25 »
Цитировать
NeoNox:
выведи отладку вместе со временем исполнения

ух. это я не то что бы не умею --- я даже не знаю как это делать. Пока. До сих пор хватало лога...
пока-пока. :)

Оффлайн NeoNox

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3012
  • +0/-0
  • 0
    • Просмотр профиля
ветвление процессов
« Ответ #6 : 10 Ноября 2004, 16:44:46 »
Вот тебе пример функции дебага.

вызываетсяя с любого доступного места как:

debug "I\'m here";

sub debug{

    my $now = localtime;
    my $data = join(\'\', @_);
    my $ra = $ENV{"REMOTE_ADDR"};

    my $msg = \'[%l] %s: %m (%d: - %h PID %p)\';
    my ($line, $subname) = (caller(1))[2,3];
    $msg =~ s/%l/$line/g;
    $msg =~ s/%s/$subname/g;
    $msg =~ s/%m/$data/g;
    $msg =~ s/%d/$now/g;
    $msg =~ s/%h/$ra/g;
    $msg =~ s/%p/$$/g;

    open (FH,">>", "./debug") or die "Can\'t open debug file: $!";
    print FH $msg."\\n";
    close FH;
}
The documentations is your friend

Оффлайн AnnA

  • Фанатка форума
  • Старожил
  • ****
  • Сообщений: 263
  • +0/-0
  • 2
    • Просмотр профиля
    • http://
ветвление процессов
« Ответ #7 : 16 Ноября 2004, 13:12:48 »
вопрос не праздный. как ограничить рождаемость детей? ;)
(презервативы не предлагать) :)
серьезно - как? хотелось бы чтобы их было не более 5 одновременно.
пока-пока. :)

Оффлайн NeoNox

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3012
  • +0/-0
  • 0
    • Просмотр профиля
ветвление процессов
« Ответ #8 : 16 Ноября 2004, 13:40:05 »
AnnA а подумать с карандашем в руке?
У тебя есть старт процесса и его конец? Вот и записывай +1 при старте процесса и отнимай при завершении.
The documentations is your friend

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28