ホームページ  >  記事  >  php教程  >  PHP プロセス間通信 - 名前付きパイプ

PHP プロセス間通信 - 名前付きパイプ

PHP中文网
PHP中文网オリジナル
2016-12-05 13:27:452295ブラウズ

PHP パイプライン通信
私のブログ: http://www.cnblogs.com/nickbai/
私の GitHub: https://github.com/nick-bai

PHP がプロセス間で通信するには、メッセージ キュー、メッセージ キュー、パイプライン、共有メモリ、ソケット、シグナル。この記事ではその方法を有名パイプを通して紹介します。

PIPE

パイプは、略語間の通信データを運ぶために使用されます。理解を容易にするために、パイプをファイルに例えると、プロセス A がパイプ P にデータを書き込み、次にプロセス B がパイプ P からデータを読み取ります。 PHP が提供するパイプライン操作 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('make Pipe false!' .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関数で子プロセスを作成します。以降、プログラムは 2 つのプロセスで実行されることに注意してください。 pcntl_fork 関数は非常に特殊で、一度呼び出すと複数の戻り値が返されます。親プロセスの場合: 子プロセスの ID を返します。この値は 0 より大きくなります。子プロセスでは0を返します。 -1 が返された場合は、作成プロセスが失敗したことを示します。 🎜🎜 行 17: 2 つのプロセスは、現在のプロセスによって取得された異なる $pid 値に基づいて異なる分岐に入ります。 🎜🎜 行 18 ~ 22: 子プロセスはパイプを開き、それに hello world を書き込み、その後スリープに入り、スリープが終了した後に終了します。 🎜🎜 行 25 ~ 29: 親プロセスはパイプを開いて読み取り、最後にコードの 29 行目を実行して子プロセスをリサイクルします。ここにはブロックされている場所が 2 つあります。1 つ目は、データが返される前に、子プロセスが終了コマンドを発行するまで待つ必要があります。プロセスをリサイクルする pcntl_wait メソッドもあります。プロセスが終了するまで待ちます。 🎜🎜 Linux でこのコードを実行してください: 🎜🎜🎜プログラムが 1 秒間ブロックし、その後 hello world を出力することがわかります。 🎜🎜 コードの 26 行目を開き、27 行目を var_dump(fread($file, 20)) .PHP_EOL; に変更すると、プログラムを実行します: 🎜🎜🎜 プログラムがすぐに空の文字列を出力して待機していることがわかります。 1 秒間 成功後に終了します。それの訳は。読み取りがノンブロッキングの場合、親プロセスは情報を読み取るときに、情報がすぐに利用可能になるのを待ちません。パイプラインに情報がない場合は、すぐに戻ります。次に、子プロセスをリサイクルするために 29 行目が実行されると、ブロックされ、子プロセスが終了するまで待機します。 🎜🎜簡単な実践例を見てみましょう。 2 つの子プロセスがファイルに情報を書き込みます。親プロセスは、ファイルの書き込みが完了したかどうかを監視し、完了後にファイルのコピーを作成します。ここでは、親プロセスと子プロセスがパイプを介して通信し、書き込みが完了したかどうかを確認します。 🎜 if(!posix_mkfifo($pipePath, 0666)){
exit("make Pipe failed n");
}
}

// ファイルを書き込むための 2 つのサブプロセスを作成します
for ( $i = 0; $i
$pid = pcntl_fork();
if( $pid == 0){
file_put_contents( './pipe.log', $i . " write Pipen", FILE_APPEND ); // ファイルを書き込みます $file = fopen( $pipePath, 'w' ); fwrite( $i . "n");エントリー完了しました。 (Fclose ($ file);
exit (); // サブプロセスを終了します}}}} // 親のプロセスを完了する必要があります:
// 完了
//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' );
exit("ok n");
}
}





声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。