今夜豚の角煮を食べたのですが、テーブルの女の子が「これは食べられるの?」と聞いてきました。私:食べられると思えば食べてもいいよ。 。 。内容に関係のないトピック
シグナルとは
シグナルは、イベント発生時のプロセスへの通知メカニズム (ソフトウェア割り込みとも呼ばれます) です。プロセスがシグナルを受信すると、カーネルはプロセスによって実行されているコードを一時停止し、対応する信号処理関数にジャンプします。処理関数が中断されない場合、処理関数の実行後、中断されたところから実行が続行されます。埋め込む。
FPM モードでコードを作成する場合、信号処理に関連する問題は発生しませんが、CLI モードの一部のメモリ常駐スクリプトは、どのようにして自由に再起動、シャットダウン、クリーンアップ作業を行うことができるのでしょうか。終了します (リンクを解除する、一時ファイルを削除するなど)?
C 信号処理の例
上の図では、信号 SIGINT## の処理関数を登録しました。
#sigint_handle、シグナルをキャプチャした後、内容を出力して終了するというシンプルでわかりやすいものです。
gcc -o run run.c && ./run を実行し、次に
CTRL C (
SIGINT シグナルがトリガーされます)、成功した出力:
Signal Captured 2! が成功すると、プログラムは直接終了します。
pcntl_signal は、上記で実装された PHP の信号処理登録メソッドです。関数は次のとおりです。基本的に C で実装されたものと同じです。違いは、現在のプロセスが終了せず、追加の
signinfo が出力されることです (PHP は C で書かれていますが、なぜ C にはシグナル関連の情報がないのですか) PHP は別の信号関数
sigaction を使用するため、興味のある方は詳細をご覧ください)
## を直接呼び出しません。 #これは、pcntl が初期化されるときです。
pcntl_signal_dispatch をティック処理関数として登録します。
が処理を登録します。 function それをシグナル コレクション (PHP のハッシュ テーブル) に入れると、php_signale4
は最終的に基礎となるシグナル管理のために sigaction
を呼び出します。
ここでは多くのコードを省略し、重要なポイントをマークしました。実際、PHP は独自のシグナル コレクションを維持しています。
pcntl_signal_dispatch が呼び出されるたびに、それが呼び出されます。上記の SIG_BLOCK
は信号をブロックするため、キー コードを実行した後でのみ信号処理関数をトリガーして、データとプログラム ロジックの整合性を確保できます。 PHP がシグナルを適切に処理する方法
私の周りでプログラマーがよく見かけますが、彼らは
PHP-FPM プロセスを再起動する必要があるとき、そのプロセスを強制終了するという手口を使っています。すべての PHP プロセスが新たに開始されます。通常は問題ありませんが、特定のプロセスのタスクが完了しない場合があり、それを直接中断するのは少々失礼です。実際、USR2
シグナルを PHP マスター プロセスに送信している限り、すべてのタスクの処理後に子プロセスが再起動されます。これはいわゆるエレガンス~## です。
#上の図は私が単純に書いた例です。プロセスを正常に終了させたい場合は、SIGTERM
シグナルを送信するだけです。SIGKILL および
SIGSTOP シグナルはシグナル ブロックをスキップしてプロセスを直接停止し、シグナルはスリープ (SLEEP)、
sleep を中断することに注意してください。実行が完了しなかった場合は残り秒数が返されるので興味のある方は試してみてください。
信号に関する知識ポイントは実際には多く、引き続き深く研究する必要があります。上記の PHP ソース コードはバージョン 7.1.25 であり、各バージョンは異なる可能性があります。