91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在php 中對信號進行處理

發布時間:2021-01-25 17:07:06 來源:億速云 閱讀:198 作者:Leah 欄目:開發技術

如何在php 中對信號進行處理?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

首先我們需要了解幾個函數

pcntl_signal   安裝信號處理器,也就是當指定信號發生時,調用函數。
pcntl_alarm   指定秒數后向進程發送SIGALRM信號。
posix_getpid 返回當前進程id
posix_kill       給指定進程發送信號

一些常用的信號說明

SIGHUP
本信號在用戶終端連接(正常或非正常)結束時發出, 通常是在終端的控制進程結束時,
通知同一session內的各個作業, 這時它們與控制終端不再關聯。

SIGINT
程序終止(interrupt)信號, 在用戶鍵入INTR字符(通常是Ctrl-C)時發出。

SIGQUIT
和SIGINT類似,但由QUIT字符(通常是Ctrl-/)來控制;進程在因收到SIGQUIT退出時會產生core文件,
在這個意義上類似于一個程序錯誤信號。

SIGKILL
用來立即結束程序的運行。本信號不能被阻塞、處理和忽略。如果管理員發現某個進程終止不了,可嘗試發送這個信號。

SIGTERM
程序結束(terminate)信號, 與SIGKILL不同的是該信號可以被阻塞和處理。通常用來要求程序自己正常退出,
shell命令kill缺省產生這個信號。如果進程終止不了,我們才會嘗試SIGKILL。

SIGUSR1
留給用戶使用

SIGUSR2
留給用戶使用

SIGALRM
時鐘定時信號, 計算的是實際的時間或時鐘時間。alarm函數使用該信號。

SIGCHLD
子進程結束時, 父進程會收到這個信號。

例1:

<?php
declare(ticks = 1);
//信號處理函數
function sig_func() {
  echo "child exit \r\n";
}
//設置信號處理器
pcntl_signal(SIGCHLD, 'sig_func');
$pid = pcntl_fork();
if($pid == -1) {
  die('fork error');
} else if ($pid) {
  pcntl_wait($status);
} else {
  echo "child... \r\n";
  exit;
}

當子進程退出時,會向父進程發送SIGCHLD信號,我們通過設置信號處理器,成功的處理信號。

例2:

<?php
declare(ticks = 1);
//信號處理函數
function sig_func($signo) {
  switch($signo) {
    case SIGCHLD: {
      echo "child SIGCHLD \r\n";
      break;
    }
    case SIGTERM: {
      echo "child SIGTERM \r\n";
      break;
    }
    default:
      //處理所有其他信號
      break;
  }
}
//設置信號處理器
pcntl_signal(SIGCHLD, 'sig_func');
//設置信號處理器
pcntl_signal(SIGTERM, 'sig_func');
$pid = pcntl_fork();
if($pid == -1) {
  die('fork error');
} else if ($pid) {
  pcntl_wait($status);
} else {
  sleep(3);
  echo "child \r\n";
  sleep(3);
  posix_kill(getmypid(), SIGTERM);
  exit;
}

父進程等待子進程的退出,子進程等待3秒后輸出child,再等待3秒后向自身發送結束程序信號。

例3:

<?php
declare(ticks = 1);
//信號處理函數
function sig_func($signo) {
  switch($signo) {
    case SIGCHLD: {
      echo "child SIGCHLD \r\n";
      break;
    }
    /*這里要把處理SIGTERM信號的代碼注釋掉
    case SIGTERM: {
      echo "child SIGTERM \r\n";
      break;
    }*/
    default:
      //處理所有其他信號
      break;
  }
}
//設置信號處理器
pcntl_signal(SIGCHLD, 'sig_func');
//設置信號處理器,也注釋掉
//不然當父進程發向子進程發送SIGTERM信號時,子進程不會退出,還會繼續執行
//我們的信號處理函數把SIGTERM給忽略了
//pcntl_signal(SIGTERM, 'sig_func');
$pid = pcntl_fork();
if($pid == -1) {
  die('fork error');
} else if ($pid) {
  sleep(30);
  posix_kill($pid, SIGTERM);
} else {
  $cnt = 0;
  for(;;) {
    sleep(3);
    echo $cnt, '-';
    ++$cnt;
  }
  exit;
}

父進程在等待30秒后,向子進程發送SIGTERM結束程序信號。如果我們設置了SIGTERM信號的處理器,并且在自定義信號處理器中并沒有殺死該進程,則該子進程會一直運行下去。

pcntl_signal()函數僅僅是注冊信號和它的處理方法,真正接收到信號并調用其處理方法的是pcntl_signal_dispatch()函數。

例4:

<?php
//使用ticks需要PHP 4.3.0以上版本
//declare(ticks = 1);
function sig_func() {
  echo "SIGALRM \r\n";
}
//設置信號處理器
pcntl_signal(SIGALRM, 'sig_func');
pcntl_alarm(3);

通過函數pcntl_alarm()3秒后給進程發送SIGALRM信號,但信號處理函數并未調用。
原因是我們注釋了declare(ticks = 1);這段代碼,而又沒有調用pcntl_signal_dispatch()函數。

declare(ticks = 1);表示每執行一條低級指令,就檢查一次信號,如果檢測到注冊的信號,就調用其信號處理器。但是這種處理方式效率很低,建議在代碼循環中通過pcntl_signal_dispatch()來處理信號。

<?php
//使用ticks需要PHP 4.3.0以上版本
//declare(ticks = 1);
function sig_func() {
  echo "SIGALRM \r\n";
}
//設置信號處理器
pcntl_signal(SIGALRM, 'sig_func');
pcntl_alarm(3);
//因為3秒后pcntl_alarm函數才會給進程發送SIGALRM信號
//所以我們通過sleep函數等待3秒后,調用pcntl_signal_dispatch()來處理信號
sleep(3);
pcntl_signal_dispatch();

pcntl_signal_dispatch()這個函數是PHP5.3以上才支持的,如果你的PHP版本大于5.3,建議使用這個方法調用信號處理器。
5.3以下的版本需要在注冊信號之前加上:declare(ticks = 1);

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

莱阳市| 无极县| 舒城县| 凉城县| 隆化县| 定兴县| 丹凤县| 德江县| 凤台县| 务川| 德兴市| 肥西县| 承德市| 泸溪县| 湖南省| 香格里拉县| 潍坊市| 井陉县| 廉江市| 莎车县| 蒙城县| 万州区| 会宁县| 无为县| 武穴市| 南溪县| 丹巴县| 长沙市| 团风县| 泉州市| 南陵县| 峨边| 修文县| 邓州市| 来安县| 赞皇县| 自贡市| 土默特右旗| 中阳县| 荥经县| 海城市|