0

我有一个网络守护程序,它在 TCP 套接字上接收固定长度(44 字节)的消息。

我正在尝试确定我应该使用 sysread 读取的最佳字节长度是多少。我当然可以做一个 sysread 44 字节的循环,但我想提出一个最佳大小。

我可以看到一个优势,而不是说,一个兆字节的数据来做 substr ,但我也可以看到为什么做一千个 sysread 调用会导致缓慢。

在公共互联网上进行 sysreads 是否有合适的大小推荐?

编辑:脚本得到一堆 44 字节的消息,它们被排队。

4

3 回答 3

2

越大越好!sysread将在任何字节可用时立即返回。

由于您永远无法保证收到完整的消息,并且您永远无法保证不会收到超过一条消息,因此您需要在 Perl 端有一个循环。由于您在 Perl 端已经有一个循环,因此您不妨一次性从系统中获取尽可能多的数据,以避免不必要的系统调用。

use constant READ_SIZE => 65*1024;

my $buf = '';
while (1) {
   my $rv = sysread($fh, $buf, READ_SIZE, length($buf));
   die if !defined($rv);
   last if !$rv;

   while ($buf =~ s/^(.{44})//s) {
      my $msg = $1;
      process_msg($msg);
   }
}

选择一个尺寸和显示器$buf的尺寸。如果它经常接近READ_SIZE,增加READ_SIZE

于 2012-05-03T03:10:55.913 回答
1

我不确定开销是多少,只有你可以衡量一个是否比另一个快,但如果我要尝试从晴朗的蓝天中选择一个大小,我会先使用4092字节。这使您最多可以处理 93 条消息,并且它在神奇的 4Kb 大小之下,这听起来是一个不错的起点。

您可以在程序运行的系统上找出页面大小,并进行相应调整。我会先int(PAGE_SIZE / MESSAGE_SIZE)看看每条消息的性能是否优于一个sysread

另一方面,perl默认使用 8KB 缓冲区

 192 /* The default buffer size for the perlio buffering layer */
 193 #ifndef PERLIOBUF_DEFAULT_BUFSIZ
 194 #define PERLIOBUF_DEFAULT_BUFSIZ (BUFSIZ > 8192 ? BUFSIZ : 8192)
 195 #endif

您可能还会发现导致更改信息的讨论。

于 2012-05-03T00:48:03.983 回答
0

系统调用不会复制未传输的字节。如果你有一个 44 字节的消息 perl 将总是返回一个 44 字节的字符串。您提供的大小只是一个最大值,用于确定提供给内核的缓冲区大小。提供超过 44 个字节的价值在于,如果排队的消息不止一条,您将在一个系统调用中将它们全部获取。

于 2012-05-03T00:01:36.083 回答