CakeFest 2024: The Official CakePHP Conference

はじめに

PHP がサポートするプロセス制御関数は、Unix 形式のプロセス生成、 プロセス実行、シグナル処理、プロセス終了機能を実装しています。 プロセス制御は Web サーバー環境で有効にするべきではなく、プロセス 制御関数のどれかが Web サーバー環境で使用された場合には、予期しない結果を 生じる可能性があります。

この文書は、プロセス制御関数の一般的な使用法を説明しようとするものです。 Unix のプロセス制御に関する詳細な情報については、fork(2), waitpid(2) および signal(2) のようなシステムのドキュメントや、 W. Richard Stevens による Advanced Programming in the UNIX Environment (Addison-Wesley) のような優れた参考書を読まれることを推奨します。

現在 PCNTL はシグナルハンドルコールバックの仕組みとして ticks を 使用しており、これは以前の仕組みよりずっと高速です。この変更は "user ticks" を使用するのと同じことです。declare() を使用して、プログラム中でコールバックの発生を許可する場所を指定する 必要があります。これにより、非同期のイベントを処理する際の オーバーヘッドを最小限に抑えることが可能となります。以前は、pcntl を 有効にして PHP をコンパイルすると、pcntl の使用の有無にかかわらず 常にこのオーバーヘッドの被害を被っていたのです。

注意: この拡張モジュールは Windows 環境では利用できません。

add a note

User Contributed Notes 3 notes

up
49
sean dot kelly at mediatile dot com
12 years ago
The following statement left me searching for answers for about a day before I finally clued in:

"Process Control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment."

At least for PHP 5.3.8 which I am using, and who knows how far back, it's not a matter of "should not", it's "can not". Even though I have compiled in PCNTL with --enable-pcntl, it turns out that it only compiles in to the CLI version of PHP, not the Apache module. As a result, I spent many hours trying to track down why function_exists('pcntl_fork') was returning false even though it compiled correctly. It turns out it returns true just fine from the CLI, and only returns false for HTTP requests. The same is true of ALL of the pcntl_*() functions.
up
5
InvisibleSmiley
3 years ago
The disabling of pcntl functions not only affects Apache servers but any non-CLI setup, e.g. nginx with PHP-FPM.

You can tell by issuing phpinfo() and looking at "disable_functions" in the Core section of the output.

It's also worth noting that this behavior can be quite misleading when you call one of the pcntl functions in a namespaced context. For example you may get:

"Call to undefined function some\custom\namespace\pcntl_signal()"

when calling pcntl_signal from a method within a namespaced class. Your first instinct may be to add a leading backslash, but that won't solve the problem. You need to check whether the function exists at runtime, unless the code is only ever executed from the CLI.
up
12
Rick Sustek
7 years ago
Actually it makes perfect sense why process control features are not supported for the Apache module. The Apache HTTP server is the chief process. It invokes the PHP module when steered to PHP by the resource requested (e.g. http://foo.php) It invokes the PHP module, typically on a new thread or a pooled thread. The PHP module then runs your script, but Apache server is still the owning process.

In this execution model, the job of your PHP script is generally to go about its business as fast as possible and return. This allows the Apache daemon to do something else useful with the thread it let you borrow. Yes, some scripts take longer to do their duty than others, but blocking the thread for extended periods is usually frowned upon.

If your script was allowed to mess with the signal handlers of the running process, it would be messing with the Apache daemon itself! That daemon has already installed signal handlers for its own use. It is just plain sense not to allow the process control operations in this context.
To Top