2012-05-25 2 views
2

내가 다음 (PHP 5.3/우분투 12.04)를 사용하여 사용자 상호 작용을 필요로하는 과정을 이야기하고 함께 사용하면는 항상 stream_select

$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"; 
} 

, PHP의 proc_open를 통해 열린 파이프에서 읽을 차단 그리고 이것은 내 테스트입니다 stream_select 경우에도 $pipes[1]가 쓰기 등을 $pipes[0] 결코 블록을 비 블록으로 설정 한 후

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

지금, 문제는 $r입니다 C의 프로그램은 항상 비어 있습니다. 그러나 상황이

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 

내가 여기서 무슨 일이 일어나고 있는지 알아낼 수 stream_select 즉 내가 읽고 테스트 프로그램에 기록 일치하는 경우없이 잘 작동합니다. 나는 웹 기반 터미널 에뮬레이터의 일종을 여기에서 달성하려고 노력하고있다. 이 작업을 수행하는 방법에 대한 제안은 언제나 환영합니다.

답변

0

죄송합니다. 나는 나중에 문제를 알아 냈다 (늦은 업데이트에 대해 유감스럽게 생각한다). 경쟁 조건으로 인해 읽기가 차단되었습니다.

프로세스에 쓰고 즉시 스트림의 가용성을 확인합니다. 쓰기 금지 및 데이터를 아직 읽을 준비가되지 않습니다 (어쨌든 1 바이트의 데이터를 사용할 수있는 경우에도 600ms가 걸렸습니다). 그래서, 나는 쓰기 블록의 끝에 sleep (1)을 추가하여 문제를 해결할 수 있었다.

+0

타임 아웃을 반복해서 선택할 수 없었습니까? –

관련 문제