php程序間通訊--訊號
阿新 • • 發佈:2018-11-28
php程序間通訊的另外一個手段就是通過 訊號 來在程序間傳遞資訊。訊號是一種系統呼叫。通常我們用的kill命令就是傳送某個訊號給某個程序的。具體有哪些訊號可以在liunx/mac中執行kill -l
檢視。
一些php訊號的意思如下:
SIGHUP | 終止程序 終端線路結束通話 |
SIGINT | 終止程序 中斷程序 |
SIGQUIT | 建立CORE檔案終止程序,並且生成core檔案 |
SIGILL | 建立CORE檔案 非法指令 |
SIGTRAP | 建立CORE檔案 跟蹤自陷 |
SIGBUS | 建立CORE檔案 匯流排錯誤 |
SIGSEGV | 建立CORE檔案 段非法錯誤 |
SIGFPE | 建立CORE檔案 浮點異常 |
SIGIOT | 建立CORE檔案 執行I/O自陷 |
SIGKILL | 終止程序 殺死程序 |
SIGPIPE | 終止程序 向一個沒有讀程序的管道寫資料 |
SIGALARM | 終止程序 計時器到時 |
SIGTERM | 終止程序 軟體終止訊號 |
SIGSTOP | 停止程序 非終端來的停止訊號 |
SIGTSTP | 停止程序 終端來的停止訊號 |
SIGCONT | 忽略訊號 繼續執行一個停止的程序 |
SIGURG | 忽略訊號 I/O緊急訊號 |
SIGIO | 忽略訊號 描述符上可以進行I/O |
SIGCHLD | 忽略訊號 當子程序停止或退出時通知父程序 |
SIGTTOU | 停止程序 後臺程序寫終端 |
SIGTTIN | 停止程序 後臺程序讀終端 |
SIGXGPU | 終止程序 CPU時限超時 |
SIGXFSZ | 終止程序 檔案長度過長 |
SIGWINCH | 忽略訊號 視窗大小發生變化 |
SIGPROF | 終止程序 統計分佈圖用計時器到時 |
SIGUSR1 | 終止程序 使用者定義訊號1 |
SIGUSR2 | 終止程序 使用者定義訊號2 |
SIGVTALRM | 終止程序 虛擬計時器到時 |
下面來看一個例子。啟動3個子程序,執行,父程序等待5秒鐘,向子程序傳送sigint訊號。子程序捕獲訊號,呼叫訊號處理函式處理。
<?php
$parentPid = posix_getpid();
echo "parent progress pid:{$parentPid}\n";
// 定義一個訊號處理函式
function sighandler($signo) {
if( $signo == SIGINT ){
$pid = getmypid();
exit("{$pid} progress,oh no ,I'm killed!\n");
}
}
//PHP < 5.3 使用
//配合pcntl_signal使用,表示每執行一條低階指令,就檢查一次訊號,如果檢測到註冊的訊號,就呼叫其訊號處理器。
//declare(ticks=1);
pcntl_signal( SIGINT, 'sighandler'); //註冊訊號處理函式
$childList = [];
for( $i = 0; $i < 3; $i++ ){
$pid = pcntl_fork();
if( $pid == 0 ){
while( true ){
//PHP >= 5.3
//呼叫已安裝的訊號處理器
//必須在迴圈裡呼叫,為了檢測是否有新的訊號等待dispatching。
pcntl_signal_dispatch();
echo "i am child " . getmypid() . " and i am running ! \n";
$sec = rand(1,2);
sleep($sec);
}
}else if( $pid == -1 ){
exit("fork fail!" . PHP_EOL);
}else{
$childList[$pid] = 1;
}
}
sleep(5);
foreach( $childList as $key=>$vo ){
posix_kill( $key, SIGINT ); //觸發SIGINIT訊號
}
sleep(2);
echo "($parentPid)parent is end " . PHP_EOL;
pcntl_signal_dispatch ( void )
呼叫每個等待訊號通過pcntl_signal() 安裝的處理器。說明一下:pcntl_signal()函式僅僅是註冊訊號和它的處理方法,真正接收到訊號並呼叫其處理方法的是pcntl_signal_dispatch()函式必須在迴圈裡呼叫,為了檢測是否有新的訊號等待dispatching。
pcntl_signal_dispatch()這個函式是PHP5.3以上才支援的,如果你的PHP版本大於5.3,建議使用這個方法呼叫訊號處理器。5.3以下的版本需要在註冊訊號之前加一句:declare(ticks = 1);表示每執行一條低階指令,就檢查一次訊號,如果檢測到註冊的訊號,就呼叫其訊號處理器。