【问题标题】:how to remove a IO::Async::Listener (or its notifier) object from a IO::Async::Loop event in perl如何从 perl 中的 IO::Async::Loop 事件中删除 IO::Async::Listener (或其通知程序)对象
【发布时间】:2012-05-23 05:47:15
【问题描述】:

我有一段代码使用 IO::Socket::UNIX 创建一个 UNIX 域套接字,并将其提供给 IO::Async::Listener 的一个实例,以处理对套接字的侦听并在接收数据时发出通知。然后,将 IO::Async::Listener 添加到 IO::Async::Loop 事件循环实例中。 当然,套接字是在受控管理器中动态创建的。

在某种情况下,我想从事件循环中删除套接字(完全删除它,或者如果可能的话在其他情况下暂时禁用它)但我不知道如何。

IO::Async::Loop 提供通过 $loop->remove( $notifier ) 从事件循环中删除 IO::Async::Notifier 对象,但创建通知器由 IO::Async::Listener 内部处理(通过 IO::Async::Stream,我猜?)。即使在我的脚本的 Ctrl-C 上,套接字文件也没有被删除,我只需要手动 close $socket and unlink( $path ) 的套接字文件吗?

这是所需行为的抽象代码:

#!/usr/bin/perl

use IO::Async::Loop;
use IO::Async::Listener;
use IO::Socket::UNIX;

my $loop = IO::Async::Loop->new;
my $listener = IO::Async::Listener->new(
                    on_stream => sub {
                            my ( undef, $stream ) = @_;

                            $stream->configure(
                                    on_read => sub {
                                            my ( $self, $buffref, $eof ) = @_;
                                            $self->write( $buffref );
                                            $buffref = "";
                                            return 0;
                                    },
                            );

                            $loop->add( $stream );
                    },
            );
$loop->add( $listener );

my $socket = IO::Socket::UNIX->new(
            Local => "echo.sock",
            Listen => 1,
            ) || die "Cannot make UNIX socket - $!\n";

$listener->listen(
            handle => $socket,
            );

my $condition = true;

while($condition) {
            // this is probably wrong
            $loop->remove( $listener );
            $condition = false;
}

【问题讨论】:

  • $socket and unlink( $path ) 有效,但这不会从 IO::Async::Loop 中删除 IO::Async::Listener 对象。

标签: perl asyncsocket unix-socket io-socket


【解决方案1】:

您在这里似乎有两个相关的问题。

您可以使用循环的remove 方法从循环中移除监听器对象:

$loop->remove( $listener )

但是,从循环中删除侦听器不会取消套接字节点与文件系统的链接。为此,您将需要您建议的 unlink 代码。

就个人而言,在像这样创建套接字的代码中,我使用了END 块:

my $path = "echo.sock";
my $socket = IO::Socket::UNIX->new(
            Local => $path,
            Listen => 1,
            ) || die "Cannot make UNIX socket - $!\n";
END { $socket and unlink $path }
$SIG{INT} = $SIG{TERM} = sub { exit 1 };

$SIG 行需要确保SIGINTSIGTERM 仍然运行END 块,而不是仅仅导致perl 进程立即终止。

最后,您应该注意,您可以使用更简洁的listen 方法,而不是在您的情况下显式创建UNIX 套接字,您可以

my $listener = ...
$loop->add( $listener );

$listener->listen(
  addr => {
    family   => "unix",
    socktype => "stream",
    path     => "echo.sock",
  },
);

虽然在这种情况下你仍然需要 END 块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多