php defunct,通过swoole观察僵尸进程和孤儿进程出现和消亡
聲明:維基百科上沒有僵死進程的詞條,這里認為僵死進程同僵尸進程,即ZOMBIE。
一、定義
什么是僵尸進程
維基百科的定義:在類UNIX系統中,僵尸進程是指完成執行(通過exit系統調用,或運行時發生致命錯誤或收到終止信號所致)但在操作系統的進程表中仍然有一個表項(進程控制塊PCB),處于”終止狀態”的進程。
這個定義很準確,但并不好理解,通俗的說法是一個進程fork了一個子進程,子進程先于父進程退出,但父進程沒有調用wait(通過wait系統調用讀取退出進程的退出態,退出進程的在進程表中的表項就被刪除),導致這個進程已經退出但是仍在進程表中占有一個位置,這種進程稱為僵尸進程。
什么是孤兒進程
孤兒進程:一個進程fork了一個子進程, 父進程先于子進程退出,運行中的子進程稱為孤兒進程。
孤兒進程將被init進程(進程號為1)所收養,并由init進程對它們完成狀態收集工作。
下面,讓我們來看2個示例:
二、僵尸進程示例
0、通過swoole在一個進程中創建子進程,讓子進程先于父進程退出。
echo 'ppid = ' . getmypid(), PHP_EOL;
$process = new swoole_process(function (swoole_process $worker) {
echo 'pid = ' . getmypid(), PHP_EOL;
sleep(10);
echo 'child process exit', PHP_EOL;
}, false);
$process->start();
sleep(1000);
echo 'parent process exit', PHP_EOL;
1、以上代碼保存文件zombie.php, 執行
[root@salmonl process]# php zombie.php
ppid = 4899
pid = 4900
child process exit
2、另開一個窗口查看進程
# 子進程退出前
$ ps aux | grep -v 'grep' | grep 'zombie'
root 4899 0.3 0.6 321644 24612 pts/0 S+ 16:07 0:00 php zombie.php
root 4900 0.0 0.2 321644 8956 pts/0 S+ 16:07 0:00 php zombie.php
# 子進程退出后
$ ps aux | grep -v 'grep' | grep 'zombie'
root 4899 0.0 0.6 321644 24612 pts/0 S+ 16:07 0:00 php zombie.php
# 查看僵尸進程(狀態為Z, 或者COMMAND中出現defunct)
$ ps aux | grep -v 'grep' | grep 'defunct'
root 4900 0.0 0.0 0 0 pts/0 Z+ 16:07 0:00
3、kill僵尸進程無效
$ kill 4900
$ ps aux | grep -v 'grep' | grep 'defunct'
root 4900 0.0 0.0 0 0 pts/0 Z+ 16:07 0:00
4、kill父進程,僵尸進程就會消亡
$ kill 4899
$ ps aux | grep -v 'grep' | grep 'defunct'
三、孤兒進程示例
0、通過swoole在一個進程中創建子進程,讓父進程先于子進程退出。
echo 'ppid = ' . getmypid(), PHP_EOL;
$process = new swoole_process(function (swoole_process $worker) {
echo 'pid = ' . getmypid(), PHP_EOL;
sleep(1000);
echo 'child process exit', PHP_EOL;
}, false);
$process->start();
sleep(10);
echo 'parent process exit', PHP_EOL;
1、以上代碼保存文件orphan.php, 執行
$ php orphan.php
ppid = 5041
pid = 5042
parent process exit
2、另開一個窗口查看進程
# 父進程退出之前,進程狀態
$ ps aux | grep -v 'grep' | grep 'orphan'
root 5041 0.5 0.6 321644 24612 pts/0 S+ 16:22 0:00 php orphan.php
root 5042 0.0 0.2 321644 8956 pts/0 S+ 16:22 0:00 php orphan.php
# 父進程退出之后進程狀態(子進程的ppid變為1)
$ ps -ef | grep -v 'grep' | grep orphan
root 5042 1 0 16:22 pts/0 00:00:00 php orphan.php
四、總結
0、swoole中避免出現僵尸進程,在父進程中調用wait即可
while ($res = swoole_process::wait()) {
echo PHP_EOL, 'worker process exit pid: ' . $res['pid'] . PHP_EOL;
}
1、僵尸進程占用進程ID,多了之后,影響進程調度。
2、清除僵尸進程可通過清除父進程,或者等待很長時間后被內核清除。
總結
以上是生活随笔為你收集整理的php defunct,通过swoole观察僵尸进程和孤儿进程出现和消亡的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vivo Y100i正式上市 512GB
- 下一篇: php获取昨日时间段内,PHP 获取 特