在 Perl 中如何判断输入文件句柄的缓冲区中是否有数据?

发布于 2024-08-11 09:28:55 字数 415 浏览 7 评论 0原文

我正在开发一个程序,该程序使用基于 epoll 的事件循环来处理多个并发套接字连接。当应用程序检测到有数据要读取时,它会调用 process_request() 子程序,该子程序使用缓冲 IO。例如:

sub process_request {
    my ( $fh ) = @_;
    if ( my $line = <$fh> ) {
        # Do something interesting
    }
}

问题在于,这里使用缓冲I/O,epoll不知道缓冲区中有未读数据在等待,因此它不会再次调用process_request()。

那么问题是,如何检测 Perl 中的 filehandle 中是否有未读数据,以便只要数据保留在缓冲区中就可以再次调用 process_request() ?

I'm working on a program that uses an epoll-based event loop to handle multiple simultaneous socket connections. When the app detects that there is data to be read, it calls a process_request() sub, which uses buffered IO. For example:

sub process_request {
    my ( $fh ) = @_;
    if ( my $line = <$fh> ) {
        # Do something interesting
    }
}

The trouble is that by using buffered I/O here, epoll doesn't know that there's unread data waiting in the buffer, so it doesn't call process_request() again.

So the question is, how can I detect if there is unread data in filehandle in Perl, so that I can call process_request() again as long as data remains in the buffer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

以可爱出名 2024-08-18 09:28:55

好吧,我知道您正在使用自己的事件循环,而不是 POE,但无论如何您可能想借用 POE 的过滤器;它们可以在不使用 POE 其余部分的情况下加载。每个套接字初始化一个POE::Filter::Line,当套接字变得可读时,对其所有内容进行非阻塞read,并使用将它们推送到过滤器中>$filter->get。返回将是(0 或更多)行的 arrayref,任何部分行将存储在过滤器中,等待行的其余部分。

如果这没有吸引力,那么,您总是可以自己重新实现相同的想法。这并不是一个巨大的工作量,主要是每个套接字的字符串缓冲区和正则表达式匹配。

Well I know that you're using your own event loop, and not POE, but you might want to borrow POE's filters anyway; they can be loaded without using the rest of POE. Initialize a POE::Filter::Line per socket, and when a socket comes readable do a nonblocking read for all it has, and push them into the filter with $filter->get. The return will be an arrayref of (0 or more) lines, and any partial lines will be stored in the filter, awaiting the rest of the line.

If that doesn't appeal, well, you could always reimplement the same idea yourself. It's not a huge amount of work, mostly a string buffer per-socket and a regex match.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文