4

PHPにスレッドがないことは知っています。しかし、このチュートリアルでは、ホスト オペレーティング システムの機能を使用してそれを実現できることを示しています。また、製品コードではこれを行わないとも述べています。なぜそれは良い考えではないのですか?

これがサンプルコードです

$processID = pcntl_fork();
if($processID) {
     echo "I'm in the parent process!";
} else {
     echo "I'm in the child process!";
}

ここにチュートリアルがあります。

4

3 に答える 3

1

PHP は、フロントエンドにサービスを提供する Web サーバー上で実行されることになっています。一般的な環境では、複数のユーザー (Web クライアント) が並行して CPU コアをフルに活用しています。作業を 1 つのスレッドから複数のスレッドに分割することは、通常、そのような環境では意味がありません。システムはすでにロードされており、スレッド化には追加の同期作業などが必要になるため、通常は「複雑な」タスクをバックエンド システムにオフロードしてから報告する方が適切です。これにより、複雑なことを行うバックエンド システムを個別にスケーリングできます。また、ジョブをキューに入れることができるので、ユーザーは即時レポート (「作業中」) を取得し、後で完了についてのレポートを取得できます。

を使用pcntl_fork()すると、プロセスのコピーが作成されます。これは、Web サーバー プロセスの完全なコピーである可能性があり、同じネットワーク接続を介してクライアントと通信しようとし (これもコピーされます)、完全な混乱を引き起こします。また、既存のデータベース接続などを混乱させることにもなります (少なくとも両方のプロセスがそれを閉じようとするため、2 番目のプロセスはデータベースによって混乱したエラーを受け取ります)。

実際のスレッド化には、プロセスのコピーを作成しないが、同じプロセスを共有するPECL の pthreads 拡張機能があり、PHP のメモリ モデルを混乱させます (一度に 1 つのスレッドに 1 つの要求があり、他の誰とも何も共有しないと仮定します)。 )これを使用する人もいますが、通常は他のシステムにオフロードする方が優れています

よくあるのは、時間がかかる IO 操作 (つまり、データベース呼び出し) です。その場合、非同期操作を使用することができます (つまりmysqli_poll、 およびを参照mysqli_reap_query)。これにより、基本的に、IO を待機し、時々 IO をチェックしながら、CPU で何かを実行できます。

于 2014-09-14T00:07:20.990 に答える
0

ここでは何も「達成」pcntl_forkされず、新しいプロセスが作成されます。複数のプロセスを作成すると、ある時点で競合状態に陥る可能性が高くなります。PHP は並列実行用に設計されていないため、あらゆる種類の奇妙なエラーや制御の問題が発生します。

1 つのプログラム内で複数のプロセスを使用することも非常に複雑になる可能性があります。相互に依存するミューテックスで同期し、アルゴリズムを順次処理する必要があります。

代わりに、お互いにメソッドを呼び出すクラスを作成できます。これにより、ほとんどすべての問題を解決できます。使用せずに解決できない問題forkは、おそらく設計が悪いためです。ウェブサイトは長時間実行されるタスクを実行する必要はありませんが、それらをキューに入れる可能性があります。crontab エントリを追加することはその一例です。

于 2014-09-13T23:49:01.597 に答える