English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
シグナル通信を使用すると、kill -l で現在のシステムのシグナルタイプを確認してください。
各シグナルが持つ詳細な意味について、この記事をご覧ください:https://ja.oldtoolbag.com/article/106040.htm
シグナルを使用する場合、php --バージョンを確認して、現在のPHPのバージョンを確認してください。プロセス間のシグナル通信を行う方法を選定しました。
[root@roverliang ipc]# php --バージョン PHP 5.6.24 (cli) (ビルド: Aug 15 2016 19:14:02) 著作権(c) 1997-2016 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
pcntl_signal_dispatch 関数を使用するには、PHP バージョン (PHP 5 >= 5.3.0, PHP 7)
PHPバージョンが以下のバージョン以下である場合、5.3.大手企業ではこのバージョンよりも低いバージョンが使用されることがあります。その場合、declare(ticks=1), 1 つの低レベル命令の実行ごとに、
信号が発生するかどうかを検出します。詳細は https://ja.oldtoolbag.com/article/48340.htm
公式サイトの説明によると、Tick(タイムキック)は、declare ブロック内でエンジンが N 条可計の低レベル命令を実行したときに発生するイベントです。N の値は、declare 内の directive 部分で ticks=N で指定されます。
低レベル文とは何でしょうか:以下のコードを参照してください:
for ($i = 0; $i < 3; $i++) { echo $i.PHP_EOL; }
それでは、この for ループには 3 つの低レベル命令が含まれています。$i を 1 つ出力するたびに、既に登録されたイベントが発生したかどうかを検出します。このようにして、効率は非常に低いです。したがって、PHPバージョンが以下のバージョン以上である場合、検出を行います5.3 。それでは、pcntl_signal_dispatch を使用して信号派送を行います。
マスタープロセスが起動する際に、いくつかの信号処理関数を登録します。
/** * @param $signal 信号 */ function signalHandal($signal) { switch ($signal) { case SIGINT: //何かを行います break; case SIGHUP: //何かを行います break; default : //何かを行います break; } }
その後、信号処理器と信号処理関数をバインドします:
//異なる信号に応じて、異なる信号処理器をインストールします。 pcntl_signal(SIGINT, 'signalHandal'); pcntl_signal(SIGHUP, 'signalHandal'); pcntl_signal(SIGUSR1, 'signalHandla');
子プロセスで信号を監視し、その信号が発生した場合、事前にインストールされた信号処理関数を呼び出します。
//信号を割り当てます。 pcntl_signal_dispatch($signal);
考え方を整理しましょう:
1、信号発生時に処理する必要のあるイベントの関数を定義します。
2、信号と信号処理関数をバインドし、信号インストールと呼びます。
3、信号を監視または配信し、既にインストールされた信号が呼び出されます。
上記の信号概念を理解したら、デモを見てみましょう:
<?php $parentpid = posix_getpid(); echo "parent progress pid:{$parentpid}\n"; //シグナルハンドラ関数を定義します function sighandler($signal) { if ($signal == SIGINT) { $pid = getmypid(); exit("{$pid} process, Killed!".PHP_EOL); } } //php version < 5.3 .低レベルコマンドの実行ごとに、シグナルが発生していないか確認します。効率が非常に悪いです。 //declare(ticks=1); $child_list = []; //シグナルハンドラを登録します。シグナルが発信された場合、定義された関数を呼び出します。 pcntl_signal(SIGINT, 'sighandler'); for($i = 0; $i < 3; $i++) { $pid = pcntl_fork(); if ($pid == 0) { //子プロセス while (true) { //既にインストールされたシグナルハンドラを呼び出し、dispatchingに新しいシグナルが待っているかを検出するために pcntl_signal_dispatch(); echo "I am child: ".getmypid(). " and i am running !".PHP_EOL; sleep(rand(1,3)); } } $child_list[] = $pid; } else { die('fork fail!'.PHP_EOL); } } sleep(5); foreach ($child_list as $key => $pid) { posix_kill($pid, SIGINT); } sleep(2); echo "{$parentpid} parent is end".PHP_EOL;