php 中的信號處理操作實(shí)例詳解
本文實(shí)例講述了php 中的信號處理操作。分享給大家供大家參考,具體如下:
首先我們需要了解幾個函數(shù)
pcntl_signal 安裝信號處理器,也就是當(dāng)指定信號發(fā)生時,調(diào)用函數(shù)。
pcntl_alarm 指定秒數(shù)后向進(jìn)程發(fā)送SIGALRM信號。
posix_getpid 返回當(dāng)前進(jìn)程id
posix_kill 給指定進(jìn)程發(fā)送信號
一些常用的信號說明
SIGHUP
本信號在用戶終端連接(正?;蚍钦?結(jié)束時發(fā)出, 通常是在終端的控制進(jìn)程結(jié)束時,
通知同一session內(nèi)的各個作業(yè), 這時它們與控制終端不再關(guān)聯(lián)。
SIGINT
程序終止(interrupt)信號, 在用戶鍵入INTR字符(通常是Ctrl-C)時發(fā)出。
SIGQUIT
和SIGINT類似,但由QUIT字符(通常是Ctrl-/)來控制;進(jìn)程在因收到SIGQUIT退出時會產(chǎn)生core文件,
在這個意義上類似于一個程序錯誤信號。
SIGKILL
用來立即結(jié)束程序的運(yùn)行。本信號不能被阻塞、處理和忽略。如果管理員發(fā)現(xiàn)某個進(jìn)程終止不了,可嘗試發(fā)送這個信號。
SIGTERM
程序結(jié)束(terminate)信號, 與SIGKILL不同的是該信號可以被阻塞和處理。通常用來要求程序自己正常退出,
shell命令kill缺省產(chǎn)生這個信號。如果進(jìn)程終止不了,我們才會嘗試SIGKILL。
SIGUSR1
留給用戶使用
SIGUSR2
留給用戶使用
SIGALRM
時鐘定時信號, 計算的是實(shí)際的時間或時鐘時間。alarm函數(shù)使用該信號。
SIGCHLD
子進(jìn)程結(jié)束時, 父進(jìn)程會收到這個信號。
例1:
<?php declare(ticks = 1); //信號處理函數(shù) function sig_func() { echo "child exit \r\n"; } //設(shè)置信號處理器 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; }
當(dāng)子進(jìn)程退出時,會向父進(jìn)程發(fā)送SIGCHLD信號,我們通過設(shè)置信號處理器,成功的處理信號。
例2:
<?php declare(ticks = 1); //信號處理函數(shù) function sig_func($signo) { switch($signo) { case SIGCHLD: { echo "child SIGCHLD \r\n"; break; } case SIGTERM: { echo "child SIGTERM \r\n"; break; } default: //處理所有其他信號 break; } } //設(shè)置信號處理器 pcntl_signal(SIGCHLD, 'sig_func'); //設(shè)置信號處理器 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; }
父進(jìn)程等待子進(jìn)程的退出,子進(jìn)程等待3秒后輸出child,再等待3秒后向自身發(fā)送結(jié)束程序信號。
例3:
<?php declare(ticks = 1); //信號處理函數(shù) 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; } } //設(shè)置信號處理器 pcntl_signal(SIGCHLD, 'sig_func'); //設(shè)置信號處理器,也注釋掉 //不然當(dāng)父進(jìn)程發(fā)向子進(jìn)程發(fā)送SIGTERM信號時,子進(jìn)程不會退出,還會繼續(xù)執(zhí)行 //我們的信號處理函數(shù)把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; }
父進(jìn)程在等待30秒后,向子進(jìn)程發(fā)送SIGTERM結(jié)束程序信號。如果我們設(shè)置了SIGTERM信號的處理器,并且在自定義信號處理器中并沒有殺死該進(jìn)程,則該子進(jìn)程會一直運(yùn)行下去。
pcntl_signal()函數(shù)僅僅是注冊信號和它的處理方法,真正接收到信號并調(diào)用其處理方法的是pcntl_signal_dispatch()函數(shù)。
例4:
<?php //使用ticks需要PHP 4.3.0以上版本 //declare(ticks = 1); function sig_func() { echo "SIGALRM \r\n"; } //設(shè)置信號處理器 pcntl_signal(SIGALRM, 'sig_func'); pcntl_alarm(3);
通過函數(shù)pcntl_alarm()3秒后給進(jìn)程發(fā)送SIGALRM信號,但信號處理函數(shù)并未調(diào)用。
原因是我們注釋了declare(ticks = 1);這段代碼,而又沒有調(diào)用pcntl_signal_dispatch()函數(shù)。
declare(ticks = 1);表示每執(zhí)行一條低級指令,就檢查一次信號,如果檢測到注冊的信號,就調(diào)用其信號處理器。但是這種處理方式效率很低,建議在代碼循環(huán)中通過pcntl_signal_dispatch()來處理信號。
<?php //使用ticks需要PHP 4.3.0以上版本 //declare(ticks = 1); function sig_func() { echo "SIGALRM \r\n"; } //設(shè)置信號處理器 pcntl_signal(SIGALRM, 'sig_func'); pcntl_alarm(3); //因?yàn)?秒后pcntl_alarm函數(shù)才會給進(jìn)程發(fā)送SIGALRM信號 //所以我們通過sleep函數(shù)等待3秒后,調(diào)用pcntl_signal_dispatch()來處理信號 sleep(3); pcntl_signal_dispatch();
pcntl_signal_dispatch()這個函數(shù)是PHP5.3以上才支持的,如果你的PHP版本大于5.3,建議使用這個方法調(diào)用信號處理器。
5.3以下的版本需要在注冊信號之前加上:declare(ticks = 1);
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《PHP進(jìn)程與線程操作技巧總結(jié)》、《PHP網(wǎng)絡(luò)編程技巧總結(jié)》、《PHP基本語法入門教程》、《PHP數(shù)組(Array)操作技巧大全》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總》
希望本文所述對大家PHP程序設(shè)計有所幫助。
相關(guān)文章
ThinkPHP6使用JWT+中間件實(shí)現(xiàn)Token驗(yàn)證實(shí)例詳解
這篇文章主要介紹了ThinkPHP6使用JWT+中間件實(shí)現(xiàn)Token驗(yàn)證的方法,結(jié)合實(shí)例形式詳細(xì)分析了JWT的功能、原理及token驗(yàn)證相關(guān)操作技巧,需要的朋友可以參考下2023-06-06基于asp+ajax和數(shù)據(jù)庫驅(qū)動的二級聯(lián)動菜單
基于asp+ajax和數(shù)據(jù)庫驅(qū)動的二級聯(lián)動菜單,需要的朋友可以參考下。2010-05-05PHP開發(fā)實(shí)現(xiàn)微信退款功能示例
這篇文章主要介紹了PHP開發(fā)實(shí)現(xiàn)微信退款功能的方法,涉及php針對微信接口的相關(guān)調(diào)用操作技巧,需要的朋友可以參考下2017-11-11CKEditor4結(jié)合php實(shí)現(xiàn)上傳圖片功能
ckedit4是沒有圖片上傳功能的,單我們可以通過配置?config.js?文件來設(shè)置圖片上傳的接口,然后結(jié)合后端程序?qū)崿F(xiàn)圖片上傳,本文講解CKEditor4結(jié)合php實(shí)現(xiàn)上傳圖片功能的方法2024-03-03