Threads in Perl

Модератор: Модераторы разделов

Аватара пользователя
plab
Сообщения: 298
ОС: Gentoo

Threads in Perl

Сообщение plab »

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

Код: Выделить всё

#!/usr/bin/perl
use threads;
use IO::Socket;

$sock = new IO::Socket::INET(PeerAddr => localhost,
                             PeerPort => 555,
                             Proto => 'tcp') or die "Can't connect\n";

push @threads, threads->create(\&msoutput, out); #создать поток для отправки
push @threads, threads->create(\&msinput, inp); #создать поток для приема

foreach my $thread (@threads) {
    $thread->join();
}

sub msoutput {           #поток для отправки
    while (1){
        $sock->send("ping\n");
        sleep 2;
    }
}

sub msinput {           #поток приема
    while ($input=<$sock>) {
        print $input;
    }
}

Для теста этого всего написал другой перл, который при приходе сообщения отправляет ответ.

Код: Выделить всё

#!/usr/bin/perl -w
use IO::Socket::INET;
$server = IO::Socket::INET->new(Listen    => SOMAXCONN,
                Reuse     => 1,
                                LocalAddr => 'localhost',
                                LocalPort => 555,
                                Proto     => 'tcp') or die "Server error\n";

while ($client = $server->accept()) {
    $client->autoflush(1);
    while ($message =  <$client>) {
        print "$message";
        print $client "OK\n";
    }
}

По идеи все правильно, но получаем:

Код: Выделить всё

E:\perl\irc>perl client
OK
Terminating on signal SIGINT(2)

Т.е. вместо того чтобы был бесконечный цикл, выполняется все только лишь один раз, но почему?
PIV 2.4GHz, 1.5GB RAM, Nvidia 7600GS && Xinerama, 420GB hdd
Спасибо сказали:
pcodr
Сообщения: 283
ОС: Debian

Re: Threads in Perl

Сообщение pcodr »

У меня работает без ошибок

plab писал(а):
01.04.2009 01:03

Код: Выделить всё

E:\perl\irc>perl client
OK
Terminating on signal SIGINT(2)


Возможно проблема в том что вы запускаете это на windows
remote system type is unix
Спасибо сказали:
Аватара пользователя
plab
Сообщения: 298
ОС: Gentoo

Re: Threads in Perl

Сообщение plab »

да, видимо проблема в этом ;) , на линуксе все работает как надо, но вот хочется знать почему
PIV 2.4GHz, 1.5GB RAM, Nvidia 7600GS && Xinerama, 420GB hdd
Спасибо сказали:
pcodr
Сообщения: 283
ОС: Debian

Re: Threads in Perl

Сообщение pcodr »

Возможно на windows у вас старая версия perl и модуля threads. Потоки в perl никогда не отличались стабильностью, тем более старые версии.
remote system type is unix
Спасибо сказали:
Аватара пользователя
plab
Сообщения: 298
ОС: Gentoo

Re: Threads in Perl

Сообщение plab »

v5.8.9 built for MSWin32-x86-multi-thread не такая уж и старая, на линуксе например версия постарше
PIV 2.4GHz, 1.5GB RAM, Nvidia 7600GS && Xinerama, 420GB hdd
Спасибо сказали:
pcodr
Сообщения: 283
ОС: Debian

Re: Threads in Perl

Сообщение pcodr »

Очевидно что проблема возникает в операции чтения строки <$sock>, которая блокирует сокет и соответственно send() не может записать в заблокированный сокет и ждет пока сокет освободится, но он не освободится т.к. <$sock> не дождется строки пришедшей от сервера потому что send() не может послать ему данные. Соответственно программа заступаривается.
Должно ли так быть или нет я затрудняюсь сказать, но очень странно что в разных ОС оно работает по разному.

Вообще в этой программе можно обойтись без потоков используя неблокирующие операции ввода-вывода.
remote system type is unix
Спасибо сказали:
Аватара пользователя
plab
Сообщения: 298
ОС: Gentoo

Re: Threads in Perl

Сообщение plab »

неблокирующие операции ввода-вывода.

посмотрел про это, очень интересно по моему, наверное так кое что и реализую. Конкретно эта программа - лишь пример, потоки все таки прийдется использовать.
PIV 2.4GHz, 1.5GB RAM, Nvidia 7600GS && Xinerama, 420GB hdd
Спасибо сказали: