僵尸进程 与 孤儿进程
引言
僵尸进程和孤儿进程的由来,都要从一个伟大的函数说起:fork()
(对,就像github里面的那个fork)
fork()的作用就是创建一个该进程下的子进程,在其exit 或 exec之前,和他共享代码,以一个父进程的身份,完成以下工作:
- 分配标识符pid和PCB
- 让子进程复制父进程的环境
- 给子进程分配地址空间和资源
- 复制父进程的地址空间信息
有了子进程,所以才有了僵尸进程和孤儿进程
僵尸进程 - 白发人送黑发人
创建子进程后,如果子进程比父进程早结束,而且父进程迟迟没有结束,那么子进程就会进入一个Z(Zombie)状态 - 僵尸状态
此时如果父进程不去处理,那么子进程就会一直处于这个状态,它毫无作用,又占了内存
因为其PCB中还保留了很多关于它的退出信息,所以它的PCB也不会被摧毁
僵尸进程在Linux中是一种数据结构
进程在结束时候,资源并不会全部释放,会保留其中的一部分信息(例如:PID信息)
正常情况下,父进程会把这些僵尸进程回收
切记:僵尸进程是有害的!
zombie.py
from multiprocessing import Process
import time
import os
def task():
print(os.getpid())
time.sleep(1)
if __name__ == '__main__':
p1 = Process(target=task, )
p2 = Process(target=task, )
p1.start()
p2.start()
print('main', os.getpid())
time.sleep(100)
[root@localhost ~]# python3 zombie.py
[root@localhost ~]# python3 zombie.py
main 1323
1324
1325
[root@localhost ~]# top
top - 17:11:47 up 6 min, 3 users, load average: 0.02, 0.09, 0.05
Tasks: 107 total, 1 running, 104 sleeping, 0 stopped, 2 zombie
%Cpu(s): 0.0 us, 0.2 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 2027892 total, 1496068 free, 239868 used, 291956 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 1631940 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 193560 6596 4136 S 0.0 0.3 0:01.28 systemd
[root@localhost ~]# ps aux | grep 1324
root 1324 0.0 0.0 0 0 pts/0 Z+ 17:11 0:00 [python3] <defunct>
root 1328 0.0 0.0 112808 964 pts/1 S+ 17:12 0:00 grep --color=auto 1324
[root@localhost ~]# ps aux | grep 1325
root 1325 0.0 0.0 0 0 pts/0 Z+ 17:11 0:00 [python3] <defunct>
root 1330 0.0 0.0 112808 964 pts/1 R+ 17:12 0:00 grep --color=auto 1325
from multiprocessing import Process
import time
import os
def task():
print(os.getpid())
time.sleep(1)
if __name__ == '__main__':
Process(target=task, ).start()
Process(target=task, ).start()
time.sleep(3)
Process(target=task, ).start()
Process(target=task, ).start()
time.sleep(5)
python主进程结束后,会回收子进程
孤儿进程 - 我生君父已老死
孤儿进程,顾名思义,子进程还在世的时候父进程却结束了
那么孤儿进程没了父进程,是不是就被孤立了呢?不会的,我们还需要了解到1号进程——init进程
它不是第一个进程,但是是用户端的第一个进程
它在用户机开启时开始工作,在用户机结束时终止
它有一个功能就是收养这些孤儿,在这些孤儿进程结束时第一时间回收他们的退出信息,保证他们不一直成为僵尸进程
所以init进程
,也被称作为孤儿院
切记:孤儿进程是无害的!
from multiprocessing import Process
import time
import os
def task():
print(os.getpid())
time.sleep(100)
if __name__ == '__main__':
Process(target=task, ).start()
Process(target=task, ).start()
print(os.getpid())
time.sleep(5)