【发布时间】:2014-08-01 09:30:16
【问题描述】:
我为系统事件文件的非阻塞输入设置了一些代码。
sysopen(FILE, $targetInput, O_NONBLOCK|O_RDONLY) or die "Failed to open $targetInput, quitting.\n";
binmode(FILE);
#More assignments and preparations here...
while (1) {
#Code that justifies non-blocking I/O here...
$rBytes = sysread(FILE, $buffer, 16);
printf("%d vs %d\n", $!, EAGAIN);
print defined($rBytes) ? "Defined!\n" : "Undef!\n";
if (!defined($rBytes) && $! == EAGAIN) {
#Nothing actually read in non-blocking mode:
usleep(1000);
} else {
#Got an event, moving on:
print "Got it!\n";
print "$rBytes!\n";
last;
}
}
#Logic using $buffer here...
这是一个非常标准的设置,有几十个例子可以用于这个东西。但是,我发现 100% 的时间,$rBytes 仍未定义,$! 设置为代码 22,EINVAL(无效参数)。已经进行了大量测试,以确保是 sysread 函数专门导致了这种情况,而在此之前绝对没有。
关键是,它有效。如您所见,我的代码假定任何 not 组合的 $rBytes 未定义(始终为真)和 $! 为 EAGAIN(始终为假)只是假设一切都很好,因为我没有添加任何错误处理。这个代码块后面是一个巨大的开关/案例;不存在的数据“无害地”通过它,循环返回以尽可能快地再次执行。
当接收到有效输入时,$rBytes仍然未定义。但是由于$! 仍然不是EAGAIN,它也传递给程序的其余部分并按预期准确运行,$buffer 包含它应该包含的内容。如果我不看一下我的 CPU 使用率计,我实际上根本不会注意到这个问题,如果它是一个快速的一次性脚本,我可能不会尝试修复它。
我可以肯定地说,“无效论点”的指控是虚假的。问题是,为什么它会给出那个错误代码,为什么$rBytes总是未定义?
【问题讨论】:
-
你在调用
print之后检查$!,而不是在调用sysread之后... -
@ikegami 那里,已修复。我显然已经尝试过其他任何挑剔的东西吗?
-
这不是吹毛求疵。
print定期将$!设置为成功。 ($!对成功毫无意义。)如果你想要一个傻瓜,那么我会指出你只修复了$!的一个用途。 -
所以你是说
sysread也返回$!==22?如果是这样,下一步是提供执行的strace。 -
Re “我已经给出了必要的东西,而不是发布 574 行几乎没有问题的代码。”你不应该给出 574 行代码,而且你没有给出必要的东西。请提供您知道会出现问题的代码。