源碼 signal_fun.php
<?php
// 設(shè)置信號處理函數(shù)
function signal_handler($signo) {
switch ($signo) {
case SIGTERM:
// 處理SIGTERM信號
tlog("Caught SIGTERM...exit...\n");
exit;
break;
case SIGHUP:
//處理SIGHUP信號
tlog("Caught SIGHUP...\n");
break;
case SIGUSR1:
tlog("Caught SIGUSR1...\n");
break;
default:
// 處理所有其他信號
}
}
// 寫日志
function tlog($message, $print=1) {
$message = posix_getpid() . '_' . $message . "\n";
if ($print) {
echo $message;
} else {
error_log(posix_getpid() . '_' . $message . "\n", 3, '/var/www/log.log');
}
}
function _system($script) {
return system("/usr/local/php/bin/php /var/www/{$script} >> /var/www/system.log");
}
源碼 main.php
<?php
include_once './signal_fun.php';
tlog('im start run');
declare(ticks=1);
// 開啟一個信號監(jiān)控
pcntl_signal(SIGTERM, 'signal_handler');
$myids = array();
while(1) {
for ($i = 0; $i < 5; ++$i) {
$mypid =pcntl_fork(); // 開啟一個子進程,子進程和父進程同時從此處向下執(zhí)行
if ($mypid < 0) { // 子進程啟動失敗
tlog('fork error!');
} elseif ($mypid == 0) { // 子進程中,讀到的進程id為0
tlog('im child!');
sleep(1000); // 子進程掛起
exit;
} else { // 父進程讀到子進程的pid
$myids[] = $mypid;
sleep(1);
}
}
sleep(10);
if ($myids) {
foreach ($myids as $key => $pid) {
tlog('kill '. $pid);
posix_kill($pid, SIGTERM); // 傳遞信號,kill 子進程
unset($myids);
sleep(2);
}
}
}
完整的執(zhí)行結(jié)果是這樣
30834_im start run
30835_im child!
30836_im child!
30837_im child!
30838_im child!
30839_im child!
30834_kill 30835
30835_Caught SIGTERM...exit...
30834_kill 30836
30836_Caught SIGTERM...exit...
30834_kill 30837
30837_Caught SIGTERM...exit...
30834_kill 30838
30838_Caught SIGTERM...exit...
30834_kill 30839
30839_Caught SIGTERM...exit...
30860_im child!
30863_im child!
30866_im child!
30869_im child!
30872_im child!
先開啟5個子進程,再殺死5個子進程,再開啟...以此循環(huán)。
我想驗證一下父進程關(guān)閉后,因為在main.php中聲明了declare(ticks=1); 所以應(yīng)該子進程時間到了之后關(guān)閉后,會自動去產(chǎn)生信號SIGTERM,由此也可以出現(xiàn) 30839_Caught SIGTERM...exit...這種提示,但是現(xiàn)在出現(xiàn)的問題是這樣
# php main.php
2356_im start run
2357_im child!
2358_im child!
2359_im child!
2360_im child!
2361_im child!
^C
# kill -9 2357
-bash: kill: (2357) - 沒有那個進程
# kill -9 2358
-bash: kill: (2358) - 沒有那個進程
# kill -9 2359
-bash: kill: (2359) - 沒有那個進程
# kill -9 2360
-bash: kill: (2360) - 沒有那個進程
# kill -9 2361
-bash: kill: (2361) - 沒有那個進程
ctrl+c關(guān)閉父進程之后,子進程沒有了...
自己剛才試了試,現(xiàn)在把所有的過程粘貼到這邊,希望后面遇到問題的有所啟發(fā)
結(jié)論:使用ctrl c干掉父進程 那么一個進程組的子進程都會被干掉
使用kill -9 pid干掉父進程 子進程還存活著,說明這兩個操作有本質(zhì)上的不同