27

私はpcntl_forkPHPについて混乱しています。

マルチスレッドに対応していると思いますが、どのように機能し、スクリプトでどのように使用しますか?

4

1 に答える 1

56

PCNTL はスレッドを作成できません。現在の PHP プロセスを「フォーク」するだけです。どういう意味ですか?を呼び出すとpcntl_fork()、現在のプロセスが 2 つのプロセスに分割されます。親プロセスの名前空間全体が子にコピーされ、両方のプロセスが並行して実行を続行しますが、1 つの違いのみがあります:pcntl_fork()親と子で子の PID を返します0

いくつかのヒント:

  • デフォルトでは無効になっています。有効にできた場合は、CLI に対してのみ有効にしてください。Web サーバーでは絶対に使用しないでください。非決定的な方法で動作します。また、マシン全体をダウンさせることもできます。無効のままにして読み進めてください。
  • プロセス間の通信は可能ですが、恐ろしいものです (共有メモリ内のシリアル化されたオブジェクトを介して)。
  • ファイル記述子 (およびデータベース接続) は共有されているため、頻繁に問題が発生します。フォーク後にDBを再接続するMySQL server has gone away必要があります。そうしないと、最初に接続を閉じたときに、フォークされたすべてのプロセスからのようなエラーが発生します。
  • 親プロセスは、子プロセスが終了するまで待たなければなりません。そうしないと、システム リソースを消費するゾンビ プロセスが残されます。

ドキュメントの例を次に示します。

<?php

$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     pcntl_wait($status); //Protect against Zombie children
} else {
     // we are the child
}

ただし、PHP は単なるスクリプト言語であることを忘れないでください。並列計算用には設計されていません。必要に応じて、CRON、メッセージキュー、または低レベル言語のプログラムを同時に実行することで、より良い仕事をすることができます。

フォークされた PHP プログラムは、読み取り、理解、およびデバッグが非常に困難です。そのプログラムを維持することは悪夢です。

間違いを犯さず、フォークを避けてください。あなたはそれを必要としません。本当に必要なのは非同期タスク ランナーです。良いニュースです。RabbitMQ素敵なチュートリアルがあります ;-) Bunnyと呼ばれる有望な RabbitMQ ライブラリを試すこともできます。

PS: fork の代わりにメッセージ キューを使用すると、もう 1 つの利点があります。複数のサーバーでキューを処理し、トラフィックの増加に合わせて水平方向にスケーリングできます。

編集 2019-03-07

私は非同期並行性フレームワークで多くのことをしてきましたがamphp、ここで言及する必要があります。単一のリクエストで非同期のノンブロッキング タスクを本当に実行する必要がある場合は、amphp今日の最良のソリューションであると考えています。php ジェネレーター ( $value = yield $promise) の概念を使用して、reactphp のような約束地獄なしで人間が読めるコードを実行します。

https://amphp.org/

于 2012-10-28T00:25:28.833 に答える