我使用stream_select(),但它返回几秒钟后0号描述符和我的功能,同时还存在要读取的数据。
一个不寻常的事情虽然是,如果你设定的超时为0,那么我总是描述符的数量为零。
$num = stream_select($read, $w, $e, 0);
我使用stream_select(),但它返回几秒钟后0号描述符和我的功能,同时还存在要读取的数据。
一个不寻常的事情虽然是,如果你设定的超时为0,那么我总是描述符的数量为零。
$num = stream_select($read, $w, $e, 0);
它是否返回数字0
或FALSE
布尔? FALSE
手段有一些错误,但零可能只是因为超时或什么有趣曾与流发生的,你应该做一个新的选择等。
我猜这可能是与零超时发生,因为它会检查并立即返回。 此外,如果你读了关于PHP手册流的选择 ,你会看到关于使用零超时这样的警告:
使用0超时值可以瞬间轮询流的状态,但是,它是不使用0超时值在一个循环中,因为它会导致你的脚本占用太多的CPU时间是个好主意。
如果这是一个TCP流,要检查连接紧密,你应该检查从返回值fread
等,以确定是否其他同行已关闭了连接错误。 关于read
流数组参数:
读阵列中列出的数据流会被关注,看看是否字符读取(更确切地说,看是否读不会阻塞变得可用 - 特别是流资源也准备对最终文件的-,在这种情况下,一个的fread()将返回一个零长度字符串)。
该stream_select()函数基本上只是民意测验你前三个参数提供的流选择,这意味着它将等到以下事件之一发生:
因此,有recieving 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”语句的第三部分是用于演示。
http://www.php.net/stream_select
由于在当前的Zend引擎的限制,不可能通过一恒定改性剂像直接NULL作为参数传递给它期望此参数通过引用传递的功能。 代替使用一个临时变量或最左边的构件是一个临时变量的表达式:
<?php $e = NULL; stream_select($r, $w, $e, 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);
}
}
粉饰什么其他的东西可能是错在那里,我的$tSec
参数stream_select被忽略,而“流”,将闲置的60秒后超时并产生EOF。
如果我在创建流后添加以下
stream_set_timeout($streams[0], 999);
stream_set_timeout($streams[1], 999);
然后我得到我想要的结果,即使有更长的时间超过60秒的底层流上没有活动。
我觉得这可能是一个错误,因为我不想让底层流上60秒钟静止之后EOF,我不希望在某些任意大的值堵塞,以避免击中超时,如果我的进程空闲一段时间。
此外,即使60秒超时仍然存在,我认为它应该只是超时我stream_select()
调用,我的循环应该能够继续。