Подскажите как скрипт такого вида cделать многопоточным или дайте ссылки на нормальные мануалы по много поточности perl. Code: #!/usr/bin/perl use Socket; %ipr = ('192.168.0.1' => '1', '192.168.0.2' => '2', '192.168.0.3' => '3'); $p='135'; foreach $ip (keys %ipr){ socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')); $iaddr = inet_aton($ip); $paddr = sockaddr_in($p, $iaddr); if(connect(SOCK, $paddr)) { print $ip." [connect]\r\n"; } else { print $ip." [error]\r\n"; } # send (SOCK, "", 0); close(SOCK); $i++; }
Code: #!/usr/bin/perl use Socket; use threads; use threads::shared; my @ipr : shared; $thr = 2; # потоки @ipr = ('192.168.0.1', '192.168.0.2', '192.168.0.3'); $p='135'; for(0..$thr) { $trl[$_] = threads->create(\&Prog, $_); } for(0..$thr) { $trl[$_]->join; } sub Prog { while (@ipr){ $ip = shift; socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')); $iaddr = inet_aton($ip); $paddr = sockaddr_in($p, $iaddr); if(connect(SOCK, $paddr)) { print $ip." [connect]\r\n"; } else { print $ip." [error]\r\n"; } # send (SOCK, "", 0); close(SOCK); $i++; } } Вроде так, только я там заюзал через массив, а не через хеш
spyder@local:~> perl tt.pl 0 [error] 1 [error] Thread 1 terminated abnormally: Bad arg length for Socket:ack_sockaddr_in, length is 0, should be 4 at /usr/lib/perl5/5.10.0/i586-linux-thread-multi/Socket.pm line 386. Thread 2 terminated abnormally: Bad arg length for Socket:ack_sockaddr_in, length is 0, should be 4 at /usr/lib/perl5/5.10.0/i586-linux-thread-multi/Socket.pm line 386. 2 [error] Thread 3 terminated abnormally: Bad arg length for Socket:ack_sockaddr_in, length is 0, should be 4 at /usr/lib/perl5/5.10.0/i586-linux-thread-multi/Socket.pm line 386. ошибки вываливаются, я думаю надо поставить проверку на не пустое значение $ip что бы их небыло
То что ты делаешь наверное можно сделать простым форком. Но раньше стандартный билды перла не подерживает потоки хоть модуль был. Для того, что их юзать надо было перекомпилировать перл Теперь вот я что прочитал http://perldoc.perl.org/threads.html Как я понял, создаёться копия перла на каждый поток. Переменый не являються общими. И для скрипта это выглядит как форк. Вывод использовать форк проще всего или взять язык который разработан для правильной работы в потоками (умеет синхронизировать код)
! Вот что я своими силама накодил поправте если где ошибки ) Code: #!/usr/bin/perl use threads; use Socket; %ipr = ('192.168.0.1' => '1', '192.168.0.2' => '2', '192.168.0.3' => '3'); $p='135'; $i =0; foreach $ip (keys %ipr){ socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')); $thr[$i]=threads->create(\&test_connect, $ip, $p); $iaddr = inet_aton($ip); $paddr = sockaddr_in($p, $iaddr); close(SOCK); $i++; } sub test_connect { $iaddr = inet_aton($ip); $paddr = sockaddr_in($p, $iaddr); if(connect(SOCK, $paddr)) { print $ip." [connect]\r\n"; return $ip; } else { print $ip." [error]\r\n"; return $ip; } # send (SOCK, "", 0); return; }
Code: use warnings; use strict; use Socket; use threads; use threads::shared; my @trl; my $p = '135'; my $threads = 2; my @ipr : shared = qw(192.168.1.1 192.168.1.2 192.168.1.3); for(0..$threads) {$trl[$_] = threads->create(\&check, $_);} for(@trl) { $_->join; } sub check { my $ip; while(@ipr) { {lock(@ipr); $ip = shift(@ipr);} socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')); my $iaddr = inet_aton($ip); my $paddr = sockaddr_in($p, $iaddr); connect(SOCK, $paddr) ? (print "$ip [connect]\r\n") : (print "$ip [error]\r\n"); close(SOCK); } }
! Вот так сказать последняя версия Code: #!/usr/bin/perl use threads; use Socket; $p = '139'; $sip = '192.168.0.'; for(1..255) { $ip = '192.168.0.'.$_; $thr[$_]=threads->create(\&conn, $ip, $p, SOCK)->join; } sub conn { socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')); $iaddr = inet_aton($ip); $paddr = sockaddr_in($p, $iaddr); if(connect(SOCK, $paddr)) { print $ip."\r\n"; close(SOCK); return; } else { close(SOCK); return; } # send (SOCK, "", 0); return; } посоветуйте как по грамотней распределять потоки потому что диапазон может быть не только от 0 до 255 но и больше а создавать 1000 потоков имхо не есть гуд ) Как лучше создовать сокет внутри фнкции или создать один а в функции юзать только connect ?
ну дак ты попробуй и тем и другим способом. посмари в каком случае быстрее с помощью time-a и сделай так как тебе выгодно.
Зачем какать, если можно выблевывать все через рот? Потому что: 1. Какать через попу легче. 2. У бодьшинства людей процесс выблевывания сопровождается неприятными ощущениями и не всегда протекает гладно. 3. Выблевывание менее гигиенично. 4. После выблевывания недостаточно вытереть рот - придется выполнять специальные процедуры для прочистки. 5. Выблевывание сопровождается потерей соли в организме. 6. Какать - более гибко. Какание происходит по типу логичный queue, в то время как для выблевывания приходится юзать неуместный stack и верхние элементы его будут необработаны.