【问题标题】:How can I tell if there is data in an input filehandle's buffer in Perl?如何判断 Perl 中输入文件句柄的缓冲区中是否有数据?
【发布时间】:2009-11-18 18:33:57
【问题描述】:

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

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

麻烦的是这里使用缓冲I/O,epoll不知道缓冲区中有未读数据在等待,所以它不会再次调用process_request()。

那么问题来了,如何在 Perl 中检测文件句柄中是否有未读数据,以便只要数据还在缓冲区中就可以再次调用 process_request()?

【问题讨论】:

  • 我撤回了我的错误答案。这里的关键点是,当缓冲区中没有任何内容时,您希望停止处理 ,但是您希望稍后会有更多数据到达缓冲区,并且您想做其他事情而不是阻塞等待它。

标签: perl sockets buffering


【解决方案1】:

好吧,我知道您使用的是自己的事件循环,而不是 POE,但您可能还是想借用 POE 的过滤器;它们可以在不使用 POE 的其余部分的情况下加载。为每个套接字初始化一个POE::Filter::Line,当一个套接字变得可读时,对它所有的做一个非阻塞的read,然后用$filter-&gt;get将它们推入过滤器。返回将是(0 或更多)行的数组引用,任何部分行都将存储在过滤器中,等待该行的其余部分。

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

【讨论】:

  • 这将改变 API 合同......但也许通过与 Tie::Handle 一起这样做,我可以完成我需要的。
  • 我假设问题是您必须与其他无法忍受其数据可能被过滤器吞噬的东西共享句柄?因为事情工作方式的唯一重大变化是数据留在了过滤器的缓冲区而不是套接字的缓冲区中。如果是这种情况,我认为你走在正确的轨道上——但请记住,你可能只使用一个对象(可能是 IO::Handle 或 IO::Socket 的子类)而不是丑陋的 tie 接口。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-22
相关资源
最近更新 更多