我正在使用stream_select()但是它会在几秒钟之后返回0个描述符和我的函数,同时仍有数据需要读取。
不同寻常的是,如果将时间设置为0,那么我总是将描述符的数量设置为零。
$num = stream_select($read, $w, $e, 0);
答案 0 :(得分:3)
是否返回数字0
或FALSE
布尔值? FALSE
表示存在一些错误,但零可能只是因为超时或流没有发生任何有趣的事情,你应该做一个新的选择等。
我猜这可能会发生零超时,因为它会检查并立即返回。此外,如果您阅读PHP manual about stream-select,您将看到有关使用零超时的警告:
使用超时值0可以即时轮询流的状态,但是,在循环中使用0超时值并不是一个好主意,因为它会导致脚本占用过多的CPU时间。
如果这是一个TCP流,并且您想要检查连接关闭,则应检查fread
等的返回值,以确定其他对等方是否已关闭连接。关于read
streams数组参数:
将监视读取数组中列出的流以查看字符是否可用于读取(更准确地说,查看读取是否不会阻塞 - 特别是,流资源在文件末尾也已准备就绪,在这种情况下,fread()将返回零长度字符串。)
答案 1 :(得分:2)
stream_select() 功能基本上只是轮询您在前三个参数中提供的流选择器,这意味着它会等到以下某个事件发生:
接收0 作为返回值完全正常,这意味着当前轮询周期中没有新数据。
我建议把这个函数放在这样的循环中:
$EOF = false;
do {
$tmp = null;
$ready = stream_select($read, $write, $excl, 0, 50000);
if ($ready === false ) {
// something went wrong!!
break;
} elseif ($ready > 0) {
foreach($read as $r) {
$tmp .= stream_get_contents($r);
if (feof($r)) $EOF = true;
}
if (!empty($tmp)) {
//
// DO SOMETHING WITH DATA
//
continue;
}
} else {
// No data in the current cycle
}
} while(!$EOF);
请注意,在此示例中,脚本完全忽略输入流之外的所有内容。此外,“if”语句的第三部分仅用于演示。
答案 2 :(得分:0)
http://www.php.net/stream_select
由于当前Zend引擎的限制,因此无法实现 直接将一个常量修饰符(如NULL)作为参数传递给a 期望此参数通过引用传递的函数。 而是使用临时变量或最左边的表达式 成员是一个临时变量:
<?php $e = NULL; stream_select($r, $w, $e, 0); ?>
答案 3 :(得分:0)
我有一个类似的问题,这是由底层套接字超时引起的。
例如。我创建了一些流
$streams = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
然后分叉,并使用如下代码块
stream_set_blocking($pipes[1], 1);
stream_set_blocking($pipes[2], 1);
$pipesToRead = array($pipes[1], $pipes[2]);
while (!feof($pipesToRead[0]) || !feof($pipesToRead[1])) {
$reads = $pipesToRead;
$writes = null;
$excepts = $pipesToRead;
$tSec = null;
stream_select($reads, $writes, $excepts, $tSec);
// while it's generating any kind of output, duplicate it wherever it
// needs to go
foreach ($reads as &$read) {
$chunk = fread($read, 8192);
foreach ($streams as &$stream)
fwrite($stream, $chunk);
}
}
关于那里可能有其他问题的问题,我对stream_select的$tSec
参数被忽略,并且在闲置60秒后,“ stream”将超时并产生EOF。
如果我在创建流后添加以下内容
stream_set_timeout($streams[0], 999);
stream_set_timeout($streams[1], 999);
然后,即使底层流上没有任何活动超过60秒,我也得到了想要的结果。
我觉得这可能是一个错误,因为我不希望底层流不活动60秒后再看到EOF,并且我不想插入任意大的值来避免超时,如果我进程空闲了一段时间。
此外,即使仍然有60秒的超时,我认为它应该只是在我的stream_select()
调用上超时,并且我的循环应该能够继续。