PHP
マルチプロセッシング
サーチ…
組み込みの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 process
をzombie process
ことはできません。
プロセス間通信
プロセス間通信により、プログラマは異なるプロセス間で通信することができます。たとえば、bashコマンドを実行して出力を印刷できるPHPアプリケーションを作成する必要があると考えてみましょう。 proc_open
を使用してコマンドを実行し、通信可能なリソースを返します。次のコードを実行される基本的な実装を示しpwd
でbash
から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()を使用して子プロセスを終了し、終了ステータスコードを返すようにしてください。