タイマー機能はPHPで実装されており、途中でPHPのマルチスレッドが使用されています。この記事ではpcntlについて説明します。
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 と Nicks
ticks は、declare(ticks = n) {statement} 構文によって定義されます。現在、declare 構文は、ticks のみを受け入れることができます。彼は、ticks = n の意味は、declare で指定されたステートメント ブロック内で N 個の低レベル ステートメントが実行されたときにイベントが発生することであると定義しています。このイベントは register_tick_function($function_name) を通じて登録できます。したがって、pcntl ファミリの関数でシグナル関連の関数を使用する場合は、前にdeclare(ticks = n) 構文構造を追加する必要があります。
$秒秒で SIGALRM 信号を送信します。pcntl_alarm メソッドを呼び出すたびに、以前に設定したクロックがキャンセルされます。
void pcntl_exec(string $path[, array $args[, array $env]]):
現在のプロセス空間でプログラムを実行します。
$path: バイナリ実行可能ファイル、または有効なスクリプト ヘッダー情報を含むスクリプト ファイル パス (#!/usr/local/bin/php) である必要があります。 args: プログラムに渡す文字列引数 リスト(配列形式) ##$envs: 環境変数 実行するプログラムの環境変数を配列形式(キー=>値形式)で渡します。
int pcntl_for k (void):
子プロセスを作成します。子プロセスは PID (プロセス番号) と PPID (親プロセス番号) のみが異なります。
作成した子プロセスの pid を返します。親スレッドが実行され、子スレッドが実行されると 0 が返され、子プロセスが作成されます。失敗すると、親プロセスのコンテキストで -1 が返され、php エラーがトリガーされます。ここで fork を実行する場合、知っておく必要があります。pcntl_fork はマークに相当するブランチ ノードを作成します。親プロセスが完了すると、子プロセスはマークから実行を開始します。つまり、pcntl_fork の後のコードが開始されます。
int pcntl_getpriority([ int $pid = getmypid()[, int $process_identifier = PRIO_PROCESS]):
指定された $pid に対応するプロセスの優先度を取得します。デフォルト値は getmypid() によって取得されます。
$pid: 指定しない場合、デフォルトは現在のプロセスです。
$process_identifier: PRIO_PGRP、PRIO_USER、PRIO_PROCESS のいずれか。このうち PRIO_PGRP はプロセス グループを取得する優先度を指します。 PRIO_USER はユーザー プロセスの優先度を取得することを指します。
値が小さいほど優先度が高くなります。 .
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 Add
bool pcntl_signal(int $signo , callback $handler[, bool $restart_syscalls = true]):
新しいシグナル ハンドラーをインストールします $指定された信号 $signo のハンドラー。
最後のパラメータは意味を理解できません。
bool pcntl_sigprocmask(int $how, array $set[, array &$oldset]):
追加、削除、または設定ロック信号、特定の動作は $how パラメータによって異なります
$how: SIG_BLOCK は現在のロック信号に信号を追加するために使用されます。そのうち、SIG_UNBLOCK は現在のロック信号から信号を削除するために使用されます。SIG_SETMASK は現在のロック信号を指定された信号リストに置き換えるために使用されます。
$set: 追加、削除、または設定される信号リスト。
$ oldset: 古いロック信号を呼び出し元に返すために使用されます。
成功した場合は TRUE、失敗した場合は FALSE を返します。
int pcntl_sigtimedwait(array $set[, array &$siginfo[, int $seconds = 0[, int $ nanoseconds = 0]]]):
pcntl_sigtimedwait は実際にpcntl_sigwaitinfo() と同じですが、pcntl_sigtimedwait にはさらに 2 つの拡張パラメータ $秒と $ナノ秒 があり、これによりスクリプトは無制限の待機時間ではなく上限の滞留時間を設定できるようになります。
$set: 待機する必要があるシグナルのリスト。 waited for
$siginfo: 待機するシグナルに関する情報を呼び出し元に返すために使用されます。情報の内容については、pcntl_sigwaitinfo
$秒: タイムアウトの秒数 数値
$ナノ秒: タイムアウトのナノ秒数。 timeout
成功後、pcntl_sigtimedwiat() はシグナル番号を返します
int pcntl_sigwaitinfo(array $set[, array &$siginfo]):
現在のスクリプトを一時停止します $set のシグナルが受信されるまで実行されます。シグナルの 1 つが到着しようとしている (たとえば、pcntl_sigprocmask によってロックされている) 場合、pcntl_sigwaitinfo はすぐに戻ります。
$set: 待機中のシグナル リスト
$siginfo: used 呼び出し元に、シグナルを待っているシグナルの情報を返します。信号には次の内容が含まれます:
1. すべての信号には次の 3 つの情報があります:
a) Signo: 信号番号
b) errno: エラー番号
c) コード: シグナル コード
2。SIGCHLD シグナル固有の情報
a) ステータス: 終了値またはシグナル
b) utime: ユーザー消費時間
c) stime: システム消費時間
d) pid: 送信プロセス ID
e) uid: 送信プロセスの実ユーザー ID##3. SIGILL、SIGFPE、SIGSEGV、SIGBUS が所有する情報
a) addr: 障害が発生したメモリの場所
4. SIGPOLL 固有の情報:
a) バンド: バンド イベント、意味不明
b) fd: ファイル記述子
関数は、操作が成功した後にシグナル番号を返します
int pcntl_wait(int &$status) [, int *options = 0]):
子プロセスが終了するまで、またはシグナルによって現在のプロセスの終了が要求されるか、呼び出し時に子プロセスが終了している場合はシグナル処理関数が呼び出されるまで、現在のプロセスをハングします。一般にゾンビ プロセスとして知られている)、この関数はすぐに戻り、すべてのシステム リソースが解放されます。
$status は、子プロセスのステータス情報を保存するために使用されます。ステータス情報は、次の関数によって生成されます。 、pcntl_wifstopped、pcntl_wifsignaled、pcntl_wexitstatus、pcntl_wtermsig、pcntl_wstopsig .
$options: システムで wait3 が許可されている場合 (ほとんどの BSD 類似システム)、オプションのオプション パラメーターを指定できます。このパラメーターが指定されていない場合、wait はシステムを使用します。システムが wait3 を許可しない場合、このパラメータは無効であり、$options の値は 0 または 2 つの定数 WNOHANG および WUNTRACED になります。
関数は、終了している子プロセスの PID、または - を返します。エラーの場合は 1、またはオプションとして WNOHANG が指定されており (wait3 が利用できないシステム)、有効な子プロセスが存在しない場合は 0 を返します。
ゾンビ プロセス: 親プロセスはフォーク後であるため、子プロセスがいつ終了するかを予測することは不可能ですしたがって、親プロセスに情報を残すために、子プロセスは、ゾンビと呼ばれる次のデータ構造を離れ、その死体を収集するために親プロセスによって開始される待機操作を待ちます。子プロセスは、実行中にゾンビプロセスと呼ばれます。子プロセスが終了(論理的に終了)してから、親プロセスがその死体を回収するまでの期間。したがって、親プロセスが終了すると、すべての子プロセスが Init に引き渡されます。ただし、親プロセスが終了しない場合、システムプロセス番号が枯渇すると、これらのゾンビプロセスが常にプロセス番号を占有してしまい、新しいプロセスを開始できなくなります。方法は、親プロセス内で自ら生成した子プロセスの死体を収集することです。
int pcntl_waitpid(int $pid, int &$status[, int $options = 0 ]):
現在のプロセスを一時停止します。指定された $pid を持つ子プロセスが終了するか、現在のプロセスが終了シグナルを受信するか、シグナル ハンドラーを呼び出すための ige シグナルを受信します。
$pid が指定されている場合、呼び出し時に対応する子プロセスが終了しています (ゾンビ状態)。この関数を実行すると、関数はすぐに戻り、すべてのシステム リソースが解放されます。
$pid: プロセス番号、-1 未満は、プロセス グループ内の子プロセスを待機していることを示します。プロセス グループ番号は絶対値です。 $pid が -1 に等しい場合は、紫禁城を待機していることを意味し、pcntl_wait 関数の動作と一致します。0 に等しい場合は、呼び出しプロセスと同じグループ内の子プロセスを待機していることを意味し、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):
指定されたステータスが子プロセスが正常に終了したことを示しているかどうかを確認します。
bool pcntl_wifsignaled(int $status):
指定されたステータスが子プロセスを終了したかどうかを確認します。 status は、子プロセスが特定のシグナルを受信したために終了したことを示します。
bool pcntl_wifstopped(int $status):
$status が子プロセスが現在停止していることを示すことができるかどうかを確認します。この関数は、動作時にのみ $status を生成します。 $options パラメータの値として pcntl_waitpid 関数によって使用される WUNTRACED のみ有効です。
int pcntl_wstopsig(int $status):
$status を分析して子プロセスを停止するシグナルの番号を返します。この関数は、pcntl_wifsignaled が TRUE を返す場合にのみ有効です。
int pcntl_wtermsig(int $status):
プロセスを中断するシグナル番号を返します。この関数は、pcntl_wifsignaled が TRUE を返す場合にのみ有効です。
PHP 丸め関数の ceil、floor、round、および intval の違いの分析
PHP でカールを使用してファイルのアップロードと受信後のシミュレーションを行う方法
# #
以上がPHPでpcntlとlibeventを使用してタイマー機能を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。