2

以下を使用してユーザーの操作を必要とするプロセスと話しています (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 ベースの端末エミュレーターを実現しようとしています。これを行う方法に関する提案は大歓迎です:)

4

1 に答える 1

0

時間を無駄にして申し訳ありません。しばらくして問題がわかりました(更新が遅れて申し訳ありません)。競合状態のため、読み取りがブロックされていました。

プロセスに書き込み、すぐにストリームの可用性を確認します。書き込みは決してブロックされず、データはまだ読み取りの準備ができていません (どういうわけか、1 バイトのデータが利用可能になるまでに 600 ミリ秒かかりました)。そのため、書き込みブロックの最後に sleep(1) を追加することで問題を解決できました。

于 2012-09-29T08:18:11.347 に答える