当与stream_select一起使用时,总是阻止从通过php的proc_open打开的管道读取

时间:2012-05-25 14:45:36

标签: php select user-interaction proc-open

我正在谈论一个需要用户使用以下内容进行交互的过程(PHP 5.3 / Ubuntu 12.04),

$pdes = array(
  0 => array('pipe', 'r'), //child's stdin
  1 => array('pipe', 'w'), //child's stdout
);
$process = proc_open($cmd, $pdes, $pipes);
sleep(1);
if(is_resource($process)){
  while($iter-->0){
    $r=array($pipes[1]);
    $w=array($pipes[0]);
    $e=array();
    if(0<($streams=stream_select($r,$w,$e,2))){
      if($streams){
        if($r){
          echo "reading\n";
          $rbuf.=fread($pipes[1],$rlen);  //reading rlen bytes from pipe
        }else{
          echo "writing\n";
          fwrite($pipes[0],$wbuf."\n");  //writing to pipe
          fflush($pipes[0]);
  }}}}
  fclose($pipes[0]);
  fclose($pipes[1]);
  echo "exitcode: ".proc_close($process)."\n";
}

这是我在C中的测试程序,

#include <stdio.h>
int main(){
  char buf[512];
  printf("before input\n");
  scanf("%s",buf);
  printf("after input\n");
  return 0;
}

现在,问题$rstream_select之后始终为空,即使$pipes[1]设置为非阻塞,而对$pipes[0]的写入永不阻止。但是,没有stream_select的情况下工作正常,即如果我匹配对测试程序的读写,

echo fread($pipes[1],$rlen);   //matching printf before input
fwrite($pipes[0],$wbuf."\n");  //matching scanf
fflush($pipes[0]);
echo fread($pipes[1],$rlen);   //matching printf after input

我无法弄清楚这里发生了什么。我试图在这里实现某种基于Web的终端模拟器。有关如何做到这一点的任何建议都是受欢迎的:)

1 个答案:

答案 0 :(得分:0)

对不起家伙浪费你的时间。我稍后想出了问题(对于后期更新感到抱歉)。由于竞争条件,读取被阻止。

我写入流程并立即检查流的可用性。永远不会写入块和数据尚未准备好读取(不知何故,即使是1字节的数据可用,也需要600ms)。所以,我能够通过在写块结束时添加sleep(1)来解决问题。