シグナルハンドラを設定する

# pcntl_signal

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

pcntl_signal — シグナルハンドラを設定する

### 説明

function pcntl_signal(int `$signal`, callable|int `$handler`, bool `$restart_syscalls` = `true`): bool

pcntl_signal() 関数は、`signal` が指すシグナルに関するハンドラを新たに設定するか、既存のハンドラを置き換えます。

### パラメータ

`signal`

  シグナル番号。

`handler`

  シグナルハンドラ。callable を渡すと、それを実行してシグナルを処理します。 あるいは、グローバル定数 `SIG_IGN` または `SIG_DFL` を渡すこともできます。それぞれ、シグナルを無視することとデフォルトのシグナルハンドラを復活させることを表します。

  callable を渡す場合は、次のシグネチャを実装したものでなければいけません。

  function handler(int `$signo`, mixed `$siginfo`): void
  `signal`
    処理するシグナル。
  `siginfo`
    OS が siginfo_t 構造体をサポートしている場合、 これはシグナルに依存するシグナル情報の配列になります。

  > 注意:

  > オブジェクトのメソッドをハンドラとして指定した場合には、 そのハンドラを別のものに変えたりスクリプトが終了したりするまでは オブジェクトのリファレンスカウントが増加したままであることに注意しましょう。

`restart_syscalls`

  再起動のシステムコールに対応するかどうかを設定します。

### 戻り値

成功した場合に `true` を、失敗した場合に `false` を返します。

### 変更履歴

バージョン | 説明
--- | ---
7.1.0 | PHP 7.1.0 以降、 ハンドラコールバックは特定のシグナルの siginfo を含む 2 番目の引数を受け付けるようになりました。 このデータは、OS が siginfo_t 構造体を持つ場合のみ提供されます。 OS が siginfo_t を実装していない場合は NULL が提供されます。

### 例

例1 pcntl_signal() の例

    <?php
    pcntl_async_signals(true);

    // シグナルハンドラ関数
    function sig_handler($signo)
    {

         switch ($signo) {
             case SIGTERM:
                 // シャットダウンの処理
                 exit;
                 break;
             case SIGHUP:
                 // 再起動の処理
                 break;
             case SIGUSR1:
                 echo "SIGUSR1 を受け取りました...\n";
                 break;
             default:
                 // それ以外のシグナルの処理
         }

    }

    echo "シグナルハンドラを設定します...\n";

    // シグナルハンドラを設定します
    pcntl_signal(SIGTERM, "sig_handler");
    pcntl_signal(SIGHUP,  "sig_handler");
    pcntl_signal(SIGUSR1, "sig_handler");

    // あるいは、オブジェクトも指定できます
    // pcntl_signal(SIGUSR1, array($obj, "do_something"));

    echo "自分自身に SIGUSR1 シグナルを送信します...\n";

    // SIGUSR1 をカレントのプロセス ID に送信します
    // posix_* 関数を使うには posix 拡張モジュールが必要です
    posix_kill(posix_getpid(), SIGUSR1);

    echo "終了\n";

    ?>

### 注意

pcntl_signal() は、既存のシグナルハンドラがある場合にはそれを上書きします。

#### ディスパッチする方法

シグナルハンドラをディスパッチするには、複数の方法があります:

- pcntl_async_signals() を有効にして非同期にディスパッチする方法。これがお勧めの方法です
- tick の頻度を設定する方法
- pcntl_signal_dispatch() を使って手動でディスパッチする方法

シグナルが非同期に、あるいは tick ベースの方法でディスパッチされた場合、 sleep() のようなブロッキング関数は中断される可能性があります。

### 参考

- » Signal (IPC) on Wikipedia
- pcntl_async_signals() - 非同期のシグナルハンドリングを有効/無効にするか、古い設定を返す
- pcntl_fork() - 現在実行中のプロセスをフォークする
- pcntl_signal_dispatch() - ペンディングシグナル用のハンドラをコールする
- pcntl_waitpid() - 待つかフォークした子プロセスのステータスを返す

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open