PHP は、pcntl と libevent を使用してタイマー関数を実装します。まず、pcntl (PHP スレッド) の例を見てみましょう。
<?php function newChild($func_name) { echo "enter newChild\n"; $args = func_get_args(); unset($args[0]); $pid = pcntl_fork(); if ($pid == 0) { function_exists($func_name) and exit(call_user_func_array($func_name, $args)) or exit(-1); } else if($pid == -1) { echo "Couldn't create child process"; } else { return $pid; } } (PS:^_^不错的php开发交流群:256271784,验证:csl,有兴趣的话可以加入进来一起讨论) function on_timer() { echo "timer called\n"; } /** * @param $func string, function name * @param $timeouts int, microtimes for time delay */ function timer($func, $timeouts){ echo "enter timer\n"; $base = event_base_new(); $event = event_new(); event_set($event, 0, EV_TIMEOUT, $func); event_base_set($event, $base); event_add($event, $timeouts); event_base_loop($base); } $pid = newChild("timer", "on_timer", 5000000); if ($pid > 0) { echo "master process exit\n"; }
PHP は、「マルチスレッド」(プロセス)
pcntl を実装するために pcntl を拡張し、ticks
ticks は、declare(ticks = n) {statement} 構文によって定義されています。現在、declare 構文は、ticks と、ticks = n の意味のみを受け入れます。このイベントは、declare で指定されたステートメント ブロック内で N 個の低レベル ステートメントが実行されると発生します。このイベントは、 register_tick_function($function_name) を通じて登録できます。そのため、pcntl のシグナル メカニズムは、ticks メカニズムに基づいています。 pcntl ファミリー関数 シグナル関連の関数を追加するときは、declare(ticks = n) 構文構造を前に追加する必要があります。
int pcntl_alarm(int $秒):
$秒は、
$秒の後にプロセスに SIGALRM シグナルを送信します。 pcntl_alarm メソッドが呼び出されるたびに、以前の設定はキャンセルされます。
$path: バイナリ実行可能ファイルであるか、有効なスクリプト ヘッダー情報 (#!/usr/local/bin/php) スクリプト ファイル パスが必要です。
$args: プログラムに渡される文字列パラメーター リスト (配列形式)
$envs: 環境変数。配列の形式 (key => value 形式) で、実行するプログラムの環境変数に渡されます。
int pcntl_for k (void):
子プロセスを作成します。親プロセスと異なるのは、PID(プロセス番号)とPPID(親プロセス番号)のみです。親スレッドが実行されると、作成された子プロセスのpidが返されます。子スレッドが実行されると、0が返されます。子プロセスの作成に失敗すると、親プロセスのコンテキストで -1 が返され、php エラーが発生します。
ここでのフォークを理解するには、次のことを理解する必要があります。 pcntl_fork は、親プロセスの作成後にブランチ ノードを作成します。つまり、pcntl_fork 以降のコードは親プロセスと子プロセスでそれぞれ 2 回実行され、2 つのプロセスの戻り値は異なります。親プロセスと子プロセスを分離して、異なるコードを実行できます。
int pcntl_getpriority([int $pid = getmypid()[, int $process_identifier = PRIO_PROCESS]]):
指定された $pid の対応する値を取得します。 process、getmypid() によって取得されるデフォルト値は現在のプロセスです。
$pid: 指定されていない場合、デフォルトは現在のプロセスです。
$process_identifier: PRIO_PGRP、PRIO_USER、PRIO_PROCESS のいずれか、デフォルトは PRIO_PROCESS です。 PRIO_PGRP はプロセスグループの優先度を取得することを指し、PRIO_USER はユーザープロセスの優先度を取得することを指し、PRIO_PROCESS は特定のプロセスの優先度を取得することを指します。
プロセスの優先度を返すか、エラーが発生した場合は false を返します。値が小さいほど優先度が高くなります。
bool pcntl_setpriority(int $priority[, int $pid = getmypid()[, int $process_identifier = PRIO_PROCESS]]:
プロセスの優先度を設定します。
$priority: 優先度の値, -20~20の範囲で、デフォルトの優先度は0です。値が小さいほど優先度が高くなります。
$pid: 指定されていない場合は、現在のプロセスを参照します。
$process_identifier: 意味は同じですpcntl_getpriority の $process_identifier として。
設定が成功した場合は TRUE を返し、失敗した場合は FALSE を返します。
bool pcntl_signal_dispatch(void):
pcntl_signal() を通じてインストールされる次のシグナルのハンドラーを呼び出します。
呼び出しは成功すると TRUE を返します。失敗した場合は false
php 5.3.3 で追加されました
bool pcntl_signal(int $signo, callback $handler[, bool $restart_syscalls = true] ):
指定された信号 $signo の新しいシグナル プロセッサ $handler をインストールします。
最後のパラメータ意味がわかりません。
bool pcntl_sigprocmask(int $how, array $set[, array &$oldset]):
ロック信号を増加、削除、または設定します。具体的な動作は、$how パラメーターによって異なります
$how: SIG_BLOCK。信号を現在のロック信号に追加するために使用され、SIG_UNBLOCK は現在のロック信号から信号を削除するために使用され、SIG_SETMASK は指定された信号を使用するために使用されます。 信号リストは現在のロック信号を置き換えます。
$set: 信号のリスト。
$oldset: 呼び出し元に古いロック信号を返すために使用されます。
成功した場合は TRUE、失敗した場合は FALSE を返します。 = 0[, int $nanoseconds = 0]]]):
pcntl_sigtimedwait は実際には pcntl_sigwaitinfo() と同じことを行いますが、pcntl_sigtimedwait にはさらに 2 つの拡張パラメーター $秒と $ナノ秒 があり、スクリプトで上限を設定できます。無限に待機するのではなく滞留時間を設定します。
$set: 待機する必要があるシグナルのリスト
$siginfo: 待機するシグナルに関する情報を呼び出し元に返すために使用されます。情報の内容については、pcntl_sigwaitinfo を参照してください。
$秒: 数値タイムアウトの秒数
$nano秒: タイムアウトのナノ秒数
成功後、pcntl_sigtimedwiat() はシグナル番号を返します
int pcntl_sigwaitinfo(array $set[, array &$siginfo]):
Hang 現在のスクリプトの実行を開始するまで$set のシグナルが受信され、シグナルの 1 つが到着しようとしている場合 (pcntl_sigprocmask によってロックされている場合など)、pcntl_sigwaitinfo はすぐに戻ります
$set: 待機中のシグナルリスト
$siginfo: used の情報を呼び出し元に返します。シグナルを待っているシグナル。これには次の内容が含まれます:
1. すべてのシグナルには次の 3 つの情報があります:
a) Signo: シグナル番号
b) errno: エラー番号
c) code: シグナルコード
2. SIGCHLD シグナル固有の情報
a) status: 終了値またはシグナル
b) utime: ユーザーの消費時間
c) stime: システムの消費時間
d) pid: 送信プロセス ID
e ) uid: 送信プロセスの実ユーザー ID
3. SIGILL、SIGFPE、SIGSEGV、SIGBUS が所有する情報
a) addr: 障害が発生したメモリの場所
4. SIGPOLL 固有の情報:
a) Band: バンド イベント、不明な
b)または、子どものプロセスが呼び出されたとき(ゾンビプロセスと呼ばれる)を呼び出します子プロセスのステータス情報を保存します。このステータス情報は次の関数によって生成されます: pcntl_wifexited、pcntl_wifstopped、pcntl_wifsignaled、pcntl_wexitstatus、pcntl_wtermsig、pcntl_wstopsig.
$options: システムで wait3 が許可されている場合 (ほとんどの BSD 類似システム)、次のことができます。オプションの options パラメータを指定します。このパラメータが指定されていない場合、wait はシステム コールを使用します。システムが wait3 を許可しない場合、このパラメータの値は 0 または 2 つの定数 WNOHANG を指定しても効果はありません。 WUNTRACED。
関数は、終了した子プロセスの PID を返すか、エラーの場合は -1 を返します。または、WNOHANG がオプションとして提供され (wait3 が利用できないシステム)、有効な子プロセスがない場合は、0 を返します
Zombie process:親プロセスがフォークした後、子プロセスがいつ終了するかを予測することは不可能です。そのため、親プロセスに情報を残すために、子プロセスはゾンビと呼ばれるデータ構造を残し、親プロセスの開始を待ちます。子プロセスが終了(論理終了)し、親プロセスがその死体を収集するための待機操作。一定時間が経過すると、子プロセスはゾンビプロセスと呼ばれます。親プロセスが終了すると、すべての子プロセスが終了します。したがって、親プロセスが終了すると、ゾンビプロセスは再利用されます。ただし、親プロセスが終了しない場合、システムプロセス番号が枯渇すると、これらのゾンビプロセスがプロセス番号を占有します。新しいプロセスを開始できなくなります。そのため、安全な方法は、親プロセス内で生成された子プロセスの死体を収集することです。 ]):
指定された $pid を持つ子プロセスが終了するか、現在のプロセスが終了シグナルを受信するか、シグナル ハンドラーを呼び出すための ige シグナルを受信するまで、現在のプロセスをハングします。
指定された $pid に対応する子プロセスが終了 (ゾンビ状態) この関数を呼び出すと、関数はすぐに戻り、すべてのシステム リソースが解放されます。
$pid: プロセス番号、-1 未満はプロセスが待機中であることを示します。 グループ内の子プロセスの場合、プロセス グループ番号。 $pid の絶対値です。-1 に等しい場合は紫禁城を待機していることを示し、pcntl_wait 関数の動作と一致します。0 に等しい場合は呼び出しプロセスと同じグループ内の子プロセスを待機していることを示します。特定のプロセスを示します。
$status: 関数から子プロセスのステータスを返すために使用されます。ステータス情報は次の関数によって生成されます: pcntl_wifexited、pcntl_wifstopped、pcntl_wifsignaled、pcntl_wexitstatus、pcntl_wtermsig、pcntl_wstopsig。
$options: 同じ意味です。 pcntl_wait の $options
int pcntl_ wexitstatus (int $status):
この関数は、pcntl_wifexited 関数が TRUE を返した場合にのみ役に立ちます。 $status パラメーターは、pcntl_waitpid によって生成されたステータス情報です。 bool pcntl_wifexited(int $status):
Check 指定されたステータスが、子プロセスが正常に終了したことを示しているかどうかを確認します。
bool pcntl_wifsignaled(int $status):
指定されたステータスが、子プロセスがシグナルの受信により終了したことを示しているかどうかを確認します。
bool pcntl_wifstopped(int $status):
$status が子プロセスが現在停止していることを示すことができるかどうかを確認します。この関数は、pcntl_waitpid 関数が $options パラメーターの値として WUNTRACED を使用するときに生成された $status に作用する場合にのみ有効です。
int pcntl_wstopsig(int $status):
分析を通じて、$status は子プロセスを停止させたシグナル番号を返します。この関数は、pcntl_wifsignaled が TRUE を返した場合にのみ有効です。この関数は、pcntl_wifsignaled が TRUE を返した場合にのみ有効です。 有効です。
pcntl と libevent を使用してタイマー関数を実装することに関するその他の PHP 関連記事については、PHP 中国語 Web サイトに注目してください。