perl – 如何在散列中保存套接字并从另一个线程循环它们?
发布时间:2020-12-15 21:49:53 所属栏目:大数据 来源:网络整理
导读:我正在使用多线程TCP服务器.在主线程中,我在套接字上侦听并为新的传入连接创建一个新线程.我想将所有传入连接保存在哈希中,以便我可以从另一个线程访问它们. 从监视器线程,我无法读取任何新添加的连接.在创建监视器线程时,似乎会创建一个新的客户端哈希. 如
我正在使用多线程TCP服务器.在主线程中,我在套接字上侦听并为新的传入连接创建一个新线程.我想将所有传入连接保存在哈希中,以便我可以从另一个线程访问它们.
从监视器线程,我无法读取任何新添加的连接.在创建监视器线程时,似乎会创建一个新的客户端哈希. 如何保留所有套接字的列表并从我的监视器线程中循环它们? 当前代码: #!/usr/bin/perl use strict; use IO::Socket; use threads; use Thread::Queue; # init my $clients = {}; my $queue = Thread::Queue->new; # thread that monitors threads->create("monitor"); # create the listen socket my $listenSocket = IO::Socket::INET->new(LocalPort => 12345,Listen => 10,Proto => 'tcp',Reuse => 1); # make sure we are bound to the port die "Cant't create a listening socket: $@" unless $listenSocket; print "Server ready. Waiting for connections on 34567 ... n"; # wait for connections at the accept call while (my $connection = $listenSocket->accept) { # set client socket to non blocking my $nonblocking = 1; ioctl($connection,0x8004667e,$nonblocking); # autoflush $connection->autoflush(1); # debug print "Accepted new connectionn"; # add to list $clients->{time()} = $connection; # start new thread and listen on the socket threads->create("readData",$connection); } sub readData { # socket parameter my ($client) = @_; # read client while (<$client>) { # remove newline chomp $_; # add to queue $queue->enqueue($_); } close $client; } sub monitor { # endless loop while (1) { # loop while there is something in the queue while ($queue->pending) { # get data from a queue my $data = $queue->dequeue; # loop all sockets while ( my ($key,$value) = each(%$clients) ) { # send to socket print $value "$datan"; } } # wait 0,25 seconds select(undef,undef,0.25); } } close $listenSocket; 解决方法
您需要通过
threads::shared 分享$client:
my $clients = &share({}); 旧式语法是由Perl原型的文档问题引起的.如果您有at least Perl 5.8.9,请使用更好的 my $clients = shared_clone({}); 代替. 您还希望使用锁来保护$client,例如 my $clients_lock : shared; { lock $clients_lock; $clients->{time()} = fileno $connection; } 最后,因为IO :: Socket :: INET实例是Perl typeglobs,你不能共享它们,所以改为将它们的套接字描述符(从 open my $fh,">&=",$sockdesc or warn ... 下面的程序将入站数据重复到其他连接的套接字: #!/usr/bin/perl use strict; use IO::Socket; use threads; use threads::shared; use Thread::Queue; # init my $clients = &share({}); my $clients_lock : shared; my $queue = Thread::Queue->new; # thread that monitors threads->create("monitor"); # create the listen socket my $port = 12345; my $listenSocket = IO::Socket::INET->new( LocalPort => $port,Listen => 10,Proto => 'tcp',Reuse => 1 ); # make sure we are bound to the port die "Can't create a listening socket: $@" unless $listenSocket; print "Server ready. Waiting for connections on $port ... n"; # wait for connections at the accept call while (my $connection = $listenSocket->accept) { # set client socket to non blocking my $nonblocking = 1; ioctl($connection,$nonblocking); # autoflush $connection->autoflush(1); # debug print "Accepted new connectionn"; # add to list { lock $clients_lock; $clients->{time()} = fileno $connection; } # start new thread and listen on the socket threads->create("readData",$connection); } sub readData { # socket parameter my ($client) = @_; # read client while (<$client>) { chomp; $queue->enqueue($_); } close $client; } sub monitor { # endless loop while (1) { # loop while there is something in the queue while ($queue->pending) { # get data from a queue my $data = $queue->dequeue; # loop all sockets { lock $clients_lock; while ( my ($key,$value) = each(%$clients) ) { # send to socket if (open my $fh,$value) { print $fh "$datan"; } else { warn "$0: fdopen $value: $!"; } } } } # wait 0,25 seconds select(undef,0.25); } } close $listenSocket; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- Delphi开发能力自我评测
- go语言学习-golang的基本数据类型
- 19.2.27 [LeetCode 96] Unique Binary Search Trees
- Delphi与.NET的互操作性
- delphi – 为什么编译器找不到我的函数的重载版本?
- Delphi – IDE从哪里选择表单名称列表?
- [VB.NET]请问哪里了可以下载到asp.net(vb.net)写的论坛
- 大数据分析平台搭建教程:基于Apache Zeppelin Notebook和R
- Lunch War with the Donkey CSU - 2084
- 01.golang hello world(sublime 安装配置汉化)