HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > ПРОГРАММИРОВАНИЕ > PHP
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

Perl многопоточночть
  #1  
Старый 27.10.2008, 20:59
zer0ska
Участник форума
Регистрация: 05.12.2007
Сообщений: 113
С нами: 9701691

Репутация: 34
По умолчанию Perl многопоточночть

Подскажите как скрипт такого вида cделать многопоточным или дайте ссылки на нормальные мануалы по много поточности perl.

Код:
#!/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++;
}
 
Ответить с цитированием

  #2  
Старый 27.10.2008, 21:07
Spyder
Members of Antichat - Level 5
Регистрация: 09.10.2006
Сообщений: 1,698
С нами: 10309346

Репутация: 4303


По умолчанию

Код:
#!/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; 27.10.2008 в 21:16..
 
Ответить с цитированием

  #3  
Старый 27.10.2008, 21:23
Spyder
Members of Antichat - Level 5
Регистрация: 09.10.2006
Сообщений: 1,698
С нами: 10309346

Репутация: 4303


По умолчанию

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 что бы их небыло
 
Ответить с цитированием

  #4  
Старый 28.10.2008, 01:54
fry
Познающий
Регистрация: 08.03.2008
Сообщений: 46
С нами: 9567020

Репутация: 17
По умолчанию

То что ты делаешь наверное можно сделать простым форком.

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

Теперь вот я что прочитал
http://perldoc.perl.org/threads.html

Как я понял, создаёться копия перла на каждый поток. Переменый не являються общими. И для скрипта это выглядит как форк.

Вывод использовать форк проще всего или взять язык который разработан для правильной работы в потоками (умеет синхронизировать код)
 
Ответить с цитированием

!
  #5  
Старый 28.10.2008, 17:26
zer0ska
Участник форума
Регистрация: 05.12.2007
Сообщений: 113
С нами: 9701691

Репутация: 34
Lightbulb !

Вот что я своими силама накодил поправте если где ошибки )
Код:
#!/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;
}
 
Ответить с цитированием

  #6  
Старый 28.10.2008, 18:07
Kaimi
Познавший АНТИЧАТ
Регистрация: 23.08.2007
Сообщений: 1,237
С нами: 9851426

Репутация: 1676


По умолчанию

Код:
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);
	}
}
 
Ответить с цитированием

  #7  
Старый 28.10.2008, 18:07
biophreak
Постоянный
Регистрация: 03.08.2007
Сообщений: 367
С нами: 9880226

Репутация: 209
По умолчанию

use warnings 'all';
use strict;
use diagnostics;
и правь
PS: И не лучше-ли сделать цикл вне функции?

Последний раз редактировалось biophreak; 28.10.2008 в 18:42..
 
Ответить с цитированием

  #8  
Старый 28.10.2008, 18:45
Spyder
Members of Antichat - Level 5
Регистрация: 09.10.2006
Сообщений: 1,698
С нами: 10309346

Репутация: 4303


По умолчанию

fry, юзать форки для этой задачи не имеет смысла, куда проще и быстрее сделать всё с потоками
 
Ответить с цитированием

!
  #9  
Старый 30.10.2008, 16:47
zer0ska
Участник форума
Регистрация: 05.12.2007
Сообщений: 113
С нами: 9701691

Репутация: 34
Lightbulb !

Вот так сказать последняя версия :-)
Код:
#!/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 ?
 
Ответить с цитированием

  #10  
Старый 30.10.2008, 16:58
zythar
Moderator - Level 7
Регистрация: 16.02.2008
Сообщений: 580
С нами: 9596486

Репутация: 291


По умолчанию

ну дак ты попробуй и тем и другим способом. посмари в каком случае быстрее с помощью time-a и сделай так как тебе выгодно.
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
BookS: PHP, PERL, MySQL, JavaScript, HTML, ajax, Веб Дизайн M1nK0 PHP 10 27.06.2009 21:35
Books Perl FRAGNATIC PHP 0 11.08.2005 16:58



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.