ホームページ  >  記事  >  バックエンド開発  >  PHPのプロセス通信をベースにしたシグナルの詳細説明

PHPのプロセス通信をベースにしたシグナルの詳細説明

墨辰丷
墨辰丷オリジナル
2018-05-25 11:32:341294ブラウズ

この記事では、PHP プロセス通信の基本におけるシグナルに関する基本的な知識と例を主に紹介します。必要な方は、

シグナル通信の使用方法を参照してください。 kill -l を使用すると、現在のシステムの信号タイプを表示できます。
各シグナルの詳細な意味については、私の記事を参照してください: http://www.jb51.net/article/106040.htm
シグナルを使用する場合、php --version バージョンを通じて現在の PHP を確認できます。プロセス間の信号通信にどの方式を使用するかが決まっています。

[root@roverliang ipc]# php --version

PHP 5.6.24 (cli) (built: Aug 15 2016 19:14:02)
Copyright (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) が使用されます。これは、低レベル命令が実行されるたびに、
がシグナルが発生したかどうかを検出することを意味します。詳しい紹介は http://www.jb51.net/article/48340.htm をご覧ください

公式 Web サイトでは次のように説明されています: Tick (クロック サイクル) は、インタープリターが N 個の低レベル ステートメントを実行するたびにタイマーになります。発生するイベントを宣言コードセグメント内で計測できます。 Nの値はdeclareのディレクティブ部分のticks=Nで指定します。

では、低レベルのステートメントとは何ですか: 次のコードに示すように:

  for ($i = 0; $i < 3; $i++) {
    echo $i.PHP_EOL;
  }

つまり、この for ループには 3 つの低レベルの命令が含まれています。 $i が出力されるたびに。ご想像のとおり、この機能は登録されたイベントが発生したかどうかを検出します。したがって、PHP が 5.3 以上であることが検出された場合は、シグナルのディスパッチには pcntl_singal_dispath を使用するだけです。

メインプロセスは、開始時にいくつかの信号処理関数を登録します。

/**
 * @param $signal 信号
 */
function signalHandal($signal)
{
  switch ($signal) {
    case SIGINT:
      //do something
      break;
    case SIGHUP:
      //do something
      break;
    default :
      //do something
      break;
  }
}

次に、シグナルプロセッサを信号処理関数にバインドします:

//根据不同的信号,安装不同的信号处理器
pcntl_signal(SIGINT, &#39;signalHandal&#39;);
pcntl_signal(SIGHUP, &#39;signalHandal&#39;);
pcntl_signal(SIGUSR1, &#39;signalHandla&#39;);

子プロセスでシグナルをリッスンし、シグナルが発生した場合は、プリインストールされた信号処理関数を呼び出します

//分配信号。
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, &#39;sighandler&#39;);



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));
    }
  } elseif($pid > 0) {
    $child_list[] = $pid;
  } else {
    die(&#39;fork fail!&#39;.PHP_EOL);
  }
}

sleep(5);
foreach ($child_list as $key => $pid) {
  posix_kill($pid, SIGINT);
}

sleep(2);
echo "{$parentpid} parent is end".PHP_EOL;


上記がこの記事の全内容です。皆さんの学習に役立つことを願っています。


関連する推奨事項:

PHP 共有メモリの使用量と signal制御例の分析

matplotlib Python に基づいた正弦波 signal の時間領域波形とスペクトログラムの例の実装

PHPプロセス信号処理中

以上がPHPのプロセス通信をベースにしたシグナルの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。