【问题标题】:Shared socket object among Perl threadsPerl 线程之间的共享套接字对象
【发布时间】:2015-01-22 19:00:11
【问题描述】:

我正在尝试创建一个可以在线程之间共享的套接字对象。以下代码不起作用,因为套接字对象是 GLOB。如何共享套接字对象?这样可以吗?

my $socket1 = IO::Socket::INET->new(
        Proto    => "tcp",
        PeerAddr => "localhost",
        PeerPort => "888",
    ) or die "couldn't connect: $!";

my $socket_shared =shared_clone($socket1);
....    
my $thr1 = threads->create(\&Thread_1); 

$thr1->join();

sub Thread_1 {

lock($socket_cpy);

my $data = "Msg.\n";
$socket1->send($data);
$socket1->recv($data,1024);

}

错误:不支持的引用类型:GLOB 在第 7 行(此处调用 shared_clone)。

【问题讨论】:

  • 你得到什么样的错误?
  • 不支持的引用类型:GLOB 在第 XX 行(shared_clone 所在的位置)。
  • 文档推荐了两件事;在分配变量之前共享变量,并且仅支持标量、数组和哈希 - 所以将您的套接字存储在 hashref 或数组对象中。

标签: multithreading perl sockets


【解决方案1】:

我可以建议您不要尝试在线程之间共享套接字吗?这感觉就像是要求它们之间存在并发问题。

虽然有(可能)这样做的方法,但我建议改为 - 为 IO 设置一个“负责”的单线程,并使用 Thread::Queue 之类的东西与之交互。

例如类似:

use strict;
use warnings;

use threads;
use Thread::Queue;
my $output_q = Thread::Queue->new();

my $nthreads = 1;

sub socket_thread {

    my $socket1 = IO::Socket::INET->new(
        Proto    => "tcp",
        PeerAddr => "localhost",
        PeerPort => "888",
    ) or die "couldn't connect: $!";

    while ( my $data = $output_q->dequeue() ) {
        $socket1->send($data);
        $socket1->recv( $data, 1024 );
    }
}


sub worker_thread {
    $output_q->enqueue( "Some text from thread: ",
        threads->self->tid(), "\n" );
}

for ( 1 .. $nthreads ) {
    threads->create( \&worker_thread );
}

foreach my $thr ( threads->list() ) {
    $thr->join();
}

这样您根本不需要传递套接字,您可以使用一个或多个队列来序列化您的 IO。这 - 在我看来 - 是首先使用 perl 线程的更强有力的理由之一 - 你有更好的 IPC 机制可以使用。

否则我很想建议使用分叉,这(在 Unix 上)通常更有效。

【讨论】:

    猜你喜欢
    • 2014-01-15
    • 1970-01-01
    • 2018-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多