我正在谈论一个需要用户交互的进程,使用以下方法(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;
}
现在,问题是$r
stream_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 字节的数据可用,也需要 600 毫秒)。因此,我能够通过在写入块末尾添加 sleep(1) 来解决问题。