>  기사  >  php教程  >  PHP 프로세스 간 통신 - 명명된 파이프

PHP 프로세스 간 통신 - 명명된 파이프

PHP中文网
PHP中文网원래의
2016-12-05 13:27:452253검색

PHP 파이프라인 통신
내 블로그: http://www.cnblogs.com/nickbai/
내 GitHub: https://github.com/nick-bai

프로세스 간 통신을 위한 PHP 메시지 큐, 파이프, 공유 메모리, 소켓, 신호 등 여러 가지 방법이 있습니다. 이번 글에서는 유명한 파이프를 통해 그 방법을 소개합니다.  

 PIPE

  파이프는 약어 간의 통신 데이터를 전달하는 데 사용됩니다. 이해를 돕기 위해 파이프를 파일과 비교할 수 있습니다. 프로세스 A는 파이프 P에 데이터를 쓴 다음 프로세스 B는 파이프 P에서 데이터를 읽습니다. PHP에서 제공하는 파이프라인 작업 API는 기본적으로 파일 작업을 위한 API와 동일합니다. 파이프라인을 생성하기 위해 posix_mkfifo 함수를 사용한다는 점을 제외하면 읽기 및 쓰기 작업은 파일 작업 함수와 동일합니다. 물론 파일을 직접 사용하여 파이프를 시뮬레이션할 수 있지만 파이프의 기능을 사용할 수는 없습니다.

파이프를 통한 통신의 일반적인 아이디어는 먼저 파이프를 만든 다음 하위 프로세스가 파이프에 정보를 쓰고 상위 프로세스가 파이프에서 정보를 읽는 것입니다. 하위 프로세스는 직접 통신할 수 있습니다. <?php<br>/**<br> * author: NickBai<br> * createTime: 2016/12/2 0002 上午 11:12<br> */<br>//创建管道<br>$pipePath = "/tmp/test.pipe";<br>if( !file_exists( $pipePath ) ){<br>    if( !posix_mkfifo( $pipePath, 0666 ) ){<br>        exit('make pipe false!' . PHP_EOL);<br>    }<br>}<br><br>//创建进程,子进程写管道,父进程读管道<br>$pid = pcntl_fork();<br><br>if( $pid == 0 ){<br>    //子进程写管道<br>    $file = fopen( $pipePath, 'w' );<br>    fwrite( $file, 'hello world' );<br>    sleep(1);<br>    exit();<br>}else{<br>    //父进程读管道<br>    $file = fopen( $pipePath, 'r' );<br>    //stream_set_blocking( $file, False );  //设置成读取非阻塞<br>    echo fread( $file, 20 ) . PHP_EOL;<br><br>    pcntl_wait($status);  //回收子进程<br>}/** * 작성자: NickBai
* createTime: 2016/12/2 0002 11:12 AM
*/
//파이프 생성
$pipePath = "/tmp/test.pipe";
if( !file_exists( $pipePath ) ){
if( !posix_mkfifo( $pipePath, 0666 ) ){
exit('파이프를 거짓으로 만드세요!' . PHP_EOL);
}
}

//만들기 프로세스, 하위 프로세스가 파이프를 쓰고, 상위 프로세스가 파이프를 읽습니다.
$pid = pcntl_fork();

if( $pid == 0 ){PHP 프로세스 간 통신 - 명명된 파이프 //자식 프로세스가 파이프를 씁니다. 파이프
$file = fopen( $pipePath, 'w' );
fwrite( $file, 'hello world' );
sleep(1);
exit();PHP 프로세스 간 통신 - 명명된 파이프} else{
/ /상위 프로세스가 파이프를 읽습니다
$file = fopen( $pipePath, 'r' );
//stream_set_blocking( $file, False ) //비차단 읽기로 설정 echo fread( $file , 20 ) . PHP_EOL;<br><br> pcntl_wait($status); //하위 프로세스 재활용<br>}
참고: 이 코드는 Linux에서만 실행될 수 있습니다. php -cli 모드에서만 실행할 수 있습니다.

7행 : 일반 파일과 다르지 않은 파이프라인의 경로를 지정합니다.
9행: posix_mkfifo 함수를 통해 파이프를 생성하고 읽기 및 쓰기 권한을 0666으로 설정합니다. 15행: pcntl_fork 함수를 통해 하위 프로세스를 생성합니다. 이제부터 프로그램은 두 가지 프로세스로 실행됩니다. pcntl_fork 함수는 일단 호출되면 여러 개의 반환 값을 갖습니다. 상위 프로세스에서: 하위 프로세스의 ID를 반환합니다. 이 값은 0보다 큽니다. 하위 프로세스에서는 0을 반환합니다. -1이 반환되면 생성 프로세스가 실패했음을 나타냅니다. 17행: 두 프로세스는 현재 프로세스에서 얻은 서로 다른 $pid 값을 기반으로 서로 다른 분기에 들어갑니다. 18~22행: 하위 프로세스가 파이프를 열고 hello world를 쓴 다음 절전 모드로 들어가고 절전 모드가 끝나면 종료됩니다. 25~29행: 상위 프로세스가 파이프를 열고 읽은 후 마지막으로 코드 29행을 실행하여 하위 프로세스를 재활용합니다. 여기에는 두 개의 차단된 위치가 있습니다. 첫 번째는 기본 읽기 위치입니다. 데이터가 반환되기 전에 하위 프로세스가 종료 명령을 내릴 때까지 기다려야 합니다. 프로세스를 재활용하는 pcntl_wait 방법도 있습니다. 프로세스가 종료될 때까지 기다리십시오. Linux에서 다음 코드를 실행하세요. 프로그램이 1초 동안 차단된 다음 hello world를 출력하는 것을 볼 수 있습니다. 코드의 26번째 줄을 열고 27번째 줄을 var_dump(fread( $file, 20 )) 으로 변경하면 프로그램을 실행할 때: 프로그램은 즉시 빈 문자열을 출력하고 종료하기 전에 1초 동안 기다립니다. 그 이유는. 읽기가 비차단인 경우 상위 프로세스가 정보를 읽을 때 정보가 즉시 사용 가능할 때까지 기다리지 않고 파이프라인에 정보가 없으면 즉시 반환됩니다. 그런 다음 29행이 자식 프로세스를 재활용하기 위해 실행되면 자식 프로세스가 종료될 때까지 차단하고 기다립니다. 간단한 실제 사례를 살펴보겠습니다. 두 개의 하위 프로세스가 파일에 정보를 씁니다. 상위 프로세스는 파일 쓰기가 완료되었는지 모니터링하고 감지하는 일을 담당합니다. 여기서 상위 프로세스와 하위 프로세스는 파이프를 통해 통신하여 쓰기가 완료되었는지 확인합니다. if( !posix_mkfifo( $pipePath, 0666 ) ){
exit("파이프 실패 n 만들기");
}
}

//파일을 쓰기 위한 두 개의 하위 프로세스 생성
for( $i = 0; $i < 2; $i++ ){

$pid = pcntl_fork();
if( $pid == 0 ){
file_put_contents( './pipe.log', $i . " write Pipen", FILE_APPEND ) //파일 쓰기
$file = fopen( $pipePath, 'w' ) ;
                                                                                                                                 who’ who who who’s who’s who’s writing, fwrite( $file, $i . "n" ) //로고를 파이프라인에 작성하면 로고 작성이 완료됩니다.
fclose( $file );
exit(); //자식 프로세스 종료
}
}

//부모 프로세스에서 수행해야 할 작업은 다음과 같습니다.
//1, 파이프에서 쓰기 상태를 읽고 완전히 쓰여졌는지 확인
//2. 작성된 파일을 복사합니다
//3. 파이프를 삭제합니다
//4. 🎜>
$file = fopen( $pipePath, 'r' );
$line = 0;
while(1){
$end = fread( $file, 1024);
foreach( str_split ( $end ) as $c) {
if ( "n" == $c ) {
$line++;
}
}

if( $ line == 2 ){
copy( './pipe.log', './pipe_copy.log' );
fclose( $file );
unlink( $pipePath );
pcntl_wait ( $status ) ;
종료("ok n");
}
}

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.