В настоящем раздёле описан многопоточный клиент gab4.pl, предназначенный для применения наряду с многопоточным психотерапевтический сервером. Он аналогичен клиенту с ветвлением gab3.pl, ориентированному на обработку потоков байтов, который описан ранее. Однако вместо ветвления дочернего процесса для чтения информации с удаленного сервера, цикл чтения происходит внутри потока, выполняющего подпрограмму do_read ().
Клиент, предназначенный для параллельной работы
#!/usг/local/bin/рer1 -w # Файл: gab4.pl # Применение: gab4.pl [хост] [порт] use strict; use IO::Socket; use Thread; use constant BUFSIZE => 1024; $SIG{TERM} = sub { exit 0 }; my $host = shift or die "Usage: gab4.pl host [port]"; my $port = shift || ’echo ’; my $socket = IO::Socket::INET->new("$host:$port”) or die $@; # Поток выполняет чтение из сокета и запись в дескриптор STDOUT my $read_thread = Thread->new (&host_to_user, $socket) ; # Главный поток выполняет чтение из дескриптора STDIN и запись в сокет user_to_host($socket); $socket->shutdown(1); $read_thread->join; sub user_to_host { my $s = shift; my $data; syswrite($s,$data) while sysread(STDIN,$data,BUFSIZE); } sub host_to__user { my $s = shift; my $data; syswrite(STDOUT,$data) while sysread($s,$data,BUFSIZE); exit 0; }
Еще одно важное различие между этой и предыдущей версией клиента состоит в том, как происходит завершение работы. В обоих клиентах при обнаружении в подпрограмме do_write () закрытия стандартного ввода, эта подпрограмма закрывает предающую половину сокета, вызывая функцию shutdown (1). В результате на сервер передается признак конца файла, что приводит к закрытию его стороны сокета, сообщение об этом событии снова передается потоку do_read ().