Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在perl中从IO::Async::Loop事件中删除IO::Async::Listener(或其通知程序)对象_Perl_Asyncsocket_Unix Socket_Io Socket - Fatal编程技术网

如何在perl中从IO::Async::Loop事件中删除IO::Async::Listener(或其通知程序)对象

如何在perl中从IO::Async::Loop事件中删除IO::Async::Listener(或其通知程序)对象,perl,asyncsocket,unix-socket,io-socket,Perl,Asyncsocket,Unix Socket,Io Socket,我有一段代码,它使用IO::socket::UNIX创建了一个UNIX域套接字,并将其提供给IO::Async::Listener的一个实例,以处理套接字上的侦听和接收数据时的通知。然后,将IO::Async::Listener添加到IO::Async::Loop事件循环实例中。 当然,套接字是在受控管理器中动态创建的 在特定条件下,我想从事件循环中删除套接字(完全删除它,或者在其他条件下暂时禁用它,如果可能的话),但我不知道如何删除 IO::Async::Loop提供了通过$Loop->rem

我有一段代码,它使用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上,套接字文件也不会被删除,我是否需要手动
关闭$socket并取消套接字文件的链接($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;
}

你这里似乎有两个相关的问题

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

$loop->remove( $listener )
但是,从循环中删除侦听器不会取消套接字节点与文件系统的链接。为此,您需要使用您建议的
取消链接
代码

就个人而言,在创建这样的套接字的代码中,我使用了
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
行来确保
SIGINT
SIGTERM
仍然运行
END
块,而不仅仅是导致
perl
进程立即终止

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

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

$listener->listen(
  addr => {
    family   => "unix",
    socktype => "stream",
    path     => "echo.sock",
  },
);
尽管在这种情况下,您仍然需要
END
块。

$socket和unlink($path)
可以工作,但这不会从IO::Async::循环中删除IO::Async::Listener对象。