サーチ…


組み込みのfork関数を使用したマルチプロセッシング

組み込み関数を使用してPHPプロセスをフォークとして実行することができます。これは、スレッドをお互いに話す必要がない場合、並列作業を実現する最も簡単な方法です。

これにより、時間のかかる作業(別のサーバーにファイルをアップロードする、電子メールを送信するなど)を別のスレッドに入れて、スクリプトの読み込み速度を向上させたり、複数のコアを使用したりすることができます。子供たちが何をしているかを知る。

Windowsでは、これにより、起動するフォークごとに別のコマンドプロンプトがポップアップすることに注意してください。

master.php

$cmd = "php worker.php 10";
if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') // for windows use popen and pclose
{
    pclose(popen($cmd,"r"));
}
else //for unix systems use shell exec with "&" in the end
{
    exec('bash -c "exec nohup setsid '.$cmd.' > /dev/null 2>&1 &"');
}

ワーカー.php

//send emails, upload files, analyze logs, etc
$sleeptime = $argv[1];
sleep($sleeptime);

フォークを使用した子プロセスの作成

PHPには、子プロセスを作成するためのpcntl_fork関数が組み込まれています。 pcntl_forkはunixのforkと同じです。これはパラメータを取りません。親プロセスと子プロセスを区別するために使用できる整数を返します。説明のために次のコードを検討してください

<?php
    // $pid is the PID of child
    $pid = pcntl_fork();
    if ($pid == -1) {
         die('Error while creating child process');
    } else if ($pid) {
         // Parent process
    } else {
         // Child process
    }
?>

ご覧のように、 -1はフォークのエラーで、子は作成されませんでした。子供の作成時には、別々のPID実行される2つのプロセスがありPID

別の考慮事項は、 zombie processまたは親プロセスが子プロセスの前に終了するプロセスがdefunct processことです。ゾンビの子プロセスを防ぐには、親プロセスの最後にpcntl_wait($status)を追加するだけです。

pnctl_waitは、子プロセスが終了するまで親プロセスの実行を中断します。

また、 SIGKILLを使用してzombie processzombie processことはできません。

プロセス間通信

プロセス間通信により、プログラマは異なるプロセス間で通信することができます。たとえば、bashコマンドを実行して出力を印刷できるPHPアプリケーションを作成する必要があると考えてみましょう。 proc_openを使用してコマンドを実行し、通信可能なリソースを返します。次のコードを実行される基本的な実装を示しpwdbashからphp

<?php
    $descriptor = array(
        0 => array("pipe", "r"), // pipe for stdin of child
        1 => array("pipe", "w"), // pipe for stdout of child
    );
    $process = proc_open("bash", $descriptor, $pipes);
    if (is_resource($process)) {
        fwrite($pipes[0], "pwd" . "\n");
        fclose($pipes[0]);
        echo stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        $return_value = proc_close($process);

    }
?>

proc_openは、記述子の指定として$descriptorを持つbashコマンドを実行します。その後、 is_resourceを使用してプロセスを検証します。いったん終了すると、ディスクリプタ仕様に従って生成された$ pipeを使って子プロセスとやりとりすることができます。

その後、単にfwriteを使って子プロセスの標準入力に書き込むことができます。この場合、 pwd後に改行が続きます。最後に、 stream_get_contentsは、子プロセスのstdoutを読み込むために使用されます。

proc_close()を使用して子プロセスを終了し、終了ステータスコードを返すようにしてください。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow