php信號處理
pcntl pcntl_signal
信號註冊函數
pcntl_alarm 指定秒數中斷程序執行任務。 每次執行只會有一個定時器生效,若之前計時器還沒結束就定義新定時器,會替代之前定時器並返回之前定時器結束前秒數,若之前計時器已完成返回0 參數設為0,會清空當前所有定時器,並不發起調用 定時器會中斷系統,即便是sleep執行中 <php declare(ticks = 1); function signal_handler($signal) { print "Caught SIGALRM\n"; echo pcntl_alarm(3).PHP_EOL;//再次調用 } pcntl_signal(SIGALRM, "signal_handler", true); echo pcntl_alarm(5).PHP_EOL;//只會調用一次 echo pcntl_alarm(3).PHP_EOL;//提示5,因為上一個計時器完成還剩5s while(1) { // } ?> pcntl_fork
創建子進程
unix創建進程效率要比線程高,但需考慮進程數和內存等限制 <?php $pid = pcntl_fork(); switch($pid) { case -1: print "Could not fork!\n"; exit; case 0://子進程 print "In child!\n"; break; default://父進程,值代表子進程PID print "In parent!\n"; } ?> pcntl_waitpid
等待或返回fork的子進程狀態
掛起當前進程的執行直到參數pid指定的進程號的進程退出, 或接收到一個信號要求中斷當前進程或調用一個信號處理函數。
如果pid指定的子進程在此函數調用時已經退出(俗稱僵屍進程),此函數 將立刻返回。
pid可選值
小於-1 等待任意進程組ID等於參數pid給定值的絕對值的進程。 -1 等待任意子進程;與pcntl_wait函數行為一致。 0 等待任意與調用進程組ID相同的子進程。 大於0 等待進程號等於參數pid值的子進程。 options WNOHANG 如果沒有子進程退出立刻返回。 WUNTRACED 子進程已經退出並且其狀態未報告時返回。
其他方式去計算本函數的返回值
pcntl_wexitstatus
檢查狀態代碼是否代表一個正常的退出。
進程共享內容 <?php for ($i = 1; $i <= 5; ++$i) { $pid = pcntl_fork(); if (!$pid) { sleep(1); print "In child $i\n"; exit($i); } } while (pcntl_waitpid(0, $status) != -1) { $status = pcntl_wexitstatus($status); echo "Child $status completed\n"; } ?> SIGCHLD: 父進程不阻塞
SIGCHLD信號會在 一個或多個 子進程結束時向父進程通知
此時再加上pcntl_waitpid loop來讓父進程及時回收全部結束的子進程
<?php declare(ticks = 1); pcntl_signal(SIGCHLD, "signal_handler"); function signal_handler($signal) { switch($signal) { case SIGCHLD: while (pcntl_waitpid(0, $status) != -1) { $status = pcntl_wexitstatus($status); echo "Child $status completed\n"; } exit; } } for ($i = 1; $i <= 5; ++$i) { $pid = pcntl_fork(); if (!$pid) { sleep(3); print "In child $i\n"; exit($i); } } while(1) { //下面的代碼會在父進程執行 echo "parent processing here".PHP_EOL; sleep(1); } ?> pcntl_exec
調用程序執行,並取代自身
<?php print "Before\n"; pcntl_exec("/usr/bin/uptime"); //下邊不會輸出 print "After\n"; ?>
php信號處理