URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID1
Нить номер: 60671
[ Назад ]

Исходное сообщение
"ускорить работу скрипта - fork?"

Отправлено jr , 06-Окт-05 08:56 
Есть скрипт perl, который поочередно опрашивает сетевые устройства (порядка 1000 штук). Что-то типа:
#!/bin/perl

@hosts = ( "192.168.0.1", "192.168.0.2", и т.д );
foreach $ip ( @hosts ) {
   $res = MyFunc ( $ip );
   print "$ip -> $res\n";
}

Процесс работы с каждым устройством занимает, например, секунд 15. Причем это время затрачивается на отклики от устройств, а не на расчеты скрипта. Отсюда логичное решение делать одновременный опрос сразу нескольких устройств для ускорения общей работы скрипта. Т.е. грубо говоря, можно породить, скажем, процессов 10, каждый процесс для одного $ip, и как только один процесс завершается, запускать новый для следующего не обработанного $ip. И так, пока не обработается весь список @hosts. Подозреваю, что мне может помочь функция fork, но как ее реализовать пока плохо понимаю...
Как это можно сделать?


Содержание

Сообщения в этом обсуждении
"ускорить работу скрипта - fork?"
Отправлено jonatan , 06-Окт-05 09:23 
http://webdesign.tria.lv/tutorials/perl/perlbook/g14.html#g1404
http://aplawrence.com/Unix/perlforkexec.html

"ускорить работу скрипта - fork?"
Отправлено kel , 06-Окт-05 09:42 
fping massive + foreach any.

"ускорить работу скрипта - fork?"
Отправлено jr , 06-Окт-05 11:30 
Вот, наваял примерчик. Покритикуйте, что не грамотно сделано.

#!/usr/bin/perl

use strict;

my $pids = {};      # хэш с запущенными процессами
my $count = 0;      # счетчик с текущим колич. процессов
my $max_count = 4;  # максимально допустимое число одновременных процессов
F: for ( my $i = 0; $i < 20; $i++ ) { # всего будет 20 процессов
   my $pid = fork();
   my $slip_var = rand() * 5 + 5;
   ##### код дочернего процесса
   if ( $pid == 0 ) {
      sleep ( $slip_var );
      print "Daemon $i with $$ pid finished.\n";
      exit 0;
   } ##### дочерний процесс завершен
   ##### код родителя
   else {
      if ( $pid ) {
         $pids->{$pid} = 1; # вносим pid дочернего процесса в список
         $count++;          # и увеличиваем счетчик
         print "Daemon $i with $pid started on $slip_var sec. ($count)\n";
      }
      else {
         print "Error: cannot fork $i with pid $pid.\n";
      }
      # если число дочек еще не равно максимальному, то запускаем еще одну
      if ( $count < $max_count ) { next F; }
      # иначе ждем завершения имеющихся
      else {
         W: while ( 1 ) {
            wait();
            foreach my $pid ( keys %{$pids} ) {
               # проверяем на наличие запущенных дочек...
               if ( getpgrp $pid == -1 ) {
                  # ... и если нет процесса, то удаляем его из списка и уменьшаем счетчик
                  $count--;
                  delete $pids->{$pid};
               }
            }
            # если дочек меньше максимально допустимого, то запускаем следующую дочку
            if ( $count < $max_count ) { last W; }
            sleep ( 1 );
         }
      }
   } ##### конец кода родителя
}


"ускорить работу скрипта - fork?"
Отправлено Skif , 06-Окт-05 12:57 
Смотри в сторону Threads это быстрее и меньше жрет памяти чем fork

"ускорить работу скрипта - fork?"
Отправлено zedi , 06-Окт-05 13:31 
>Смотри в сторону Threads это быстрее и меньше жрет памяти чем fork
>


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


"ускорить работу скрипта - fork?"
Отправлено Skif , 07-Окт-05 11:48 
>
>Тогда для каждой платформы свою реализацию Treads будешь делать. Fork универсальней, хоть
>и ресурсоемкней ...


Ну, за все приходиться платить, а при таком раскладе даже будет лучше для мультипроцессорных систем. Хотя каждый решает сам. главный недостаток threads (хотя смотря с какой стороны смотреть) то что они дут одним процессом и если процесс упал, то упали и все нити.