>Отправлено andy, 08-Май-07 09:18
>что-то типа этого подойдет или я неправильно понял задачу?
>
после того что нарисовал andy даже как то неудобно отправлять свою поделку,
по хорошему нужно твою процедуру соединений запихнуть в тред, и создать несколько тредов, но поскольку у меня перл собран без тредов, я реализовал пример в котором создается несколько процессов, они работают каждый со своей задачей(для тебя это диапазон адресов) и возвращают через пайп результаты главному процессу. Вообщем основная проблема в том что для того чтобы определить что чтото работает по сети, это то что приходиться долго ждать ответа, предлагаю решить ее тем что ждать будет не один главный процесс, а несколько подчиненных.Я написал не сетевой приложение но его легко можно под него переделать, сильная вещь получилась, особенно когда задаешь 1500 тыщи процессов. работает но у меня памяти не хватает ;-)))
вот смотри:
-----------------------------------------------------------
#!/usr/bin/perl -w
# file: fork10and_pipe_exchange.pl
use IO::File;
use POSIX 'WNOHANG';
use strict;
my $max_proc_pool = 1500;
my $max_worker_cycle = 10;
my $quit = 0;
my (%childs, $i, $child);
my $cnt_worker;
#Обработка сигнала завершения дочернего процесса
sub sig_child {
my $child;
while(($child = waitpid(-1, WNOHANG)) > 0) {
my $id = $childs{$child};
if(defined($id)) {
#можно пометить процесс как убитый, а можно и ничего не делать
#$childs{$child} = 0;
print "Kiled child id $id, PID($child)\n";
} else {
print "Kiled unknown child PID($child)\n";
}
$cnt_worker--;
}
}
$SIG{PIPE} = 'IGNORE';
$SIG{CHLD} = 'sig_child';
#может быть здесь стоит убить порожденные процессы ?
$SIG{TERM} = $SIG{INT} = sub{$quit++};
#Порождаем процессы которые будут выполнять основную работу и докладывать "хозяину"
pipe(READER, WRITER) or die "pipe no good: $!";
$| = 1;
for($i = 0; $i < $max_proc_pool; $i++) {
$child = fork();
die "Can't fork: $!" unless defined $child;
if ($child == 0) { #Work inchild process
do_child();
exit(0);
}
$childs{$child} = $i;
print "Build child pid $child id $i\n";
}
close WRITER;
print "I build $i worker\n";
$cnt_worker = $i;
#Начнем обработку "докладов" от процессов
my $in = "";
my ($mess, $id);
while(!$quit and ($cnt_worker > 0) and defined ($in = <READER>)){
chomp $in;
($child,$mess) = split(/:/,$in);
$id = $childs{$child};
print "Parent: child id '$id' pid($child) - report: $mess\n";
#sleep 1;
}
#Определим причину по которой завершилась программа
if($quit) {
print "Exit by quit = $quit\n";
print "cnt_worker is $cnt_worker\n";
}
if($cnt_worker <= 0) {
print "Exit by all childs ended!\n";
print "quit is $quit\n";
print "cnt_worker is $cnt_worker\n";
}
if(!defined($in)) {
print "Exit by undef 'input' variable!\n";
print "quit is $quit\n";
print "cnt_worker is $cnt_worker\n";
}
print "--------------- A parent End print---------------------\n";
exit(0);
#Процедура в которой выполняется работа дочерним процессом
sub do_child {
close READER;
my $quit_child = 0;
$SIG{TERM} = $SIG{INT} = sub{$quit_child++};
sleep(1);
select WRITER; $| = 1;
select STDOUT;
for(my $i = 0; $i < $max_worker_cycle; $i++) {
print WRITER "$$:$i\n";
sleep(1);
if($quit_child > 0) {
print "child $$ terminated!!!\n";
close WRITER;
exit(0);
}
}
close WRITER;
print "child PID $$ ended!\n";
}