zombie/orphan process

zombie process / orphan process

父进程通过fork()函数来创建子进程。子进程会copy 当前父进程的状态和运行代码,独立运行,子进程和父进程的的运行和结束是一个异步的过程,fork出来之后运行的先后顺序也取决于系统的调度,不存在绝对的顺序。linux 为了进程退出能被正确回收,会维护一张进程的映射表,当进程结束时,系统会将进程的信息存储起来,等待父进程去处理回收子进程,处于退出状态且父进程没有调用wait()获取状态信息的进程就会陷入Z 状态,理论上所有的进程都会有一个短暂的Z 状态。

  • orphan process:一个父进程退出,而子进程还在运行,这些子进程将成为孤儿进程,被init进程所收养,并由init进程对它们完成状态收集工作。

  • zombie process:进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。

如何处理僵尸进程/孤儿进程

  • orphan process
    理论上孤儿进程不会对系统有影响,init 进程会接管成为父进程,负责进程回收,linux中也会有很多主动的操作来避免子进程被主动回收,比如说nohupdisown ,都是通过屏蔽信号来使子进程成为orphan process最终被init接收,实现终端关闭但是进程不退出
  • zombie process
    理论上zombie process是由于父进程不wait(), 可以直接干掉父进程,让init接手来处理

fork()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
pid = fork()

if pid > 0 { printf "this is father"}
if pid = 0 { printf "this is child" }
if pid < 0 { printf "fork error" }

fork()后会copy一个进程出来,fork后的代码会分布在子进程和当前进程中独立运行。也就是会有2次输出。
linux man page的说明:

DESCRIPTION
The fork extension adds three functions, as follows.

fork() This function creates a new process. The return value is the zero in the child and the process-id number of the
child in the parent, or -1 upon error. In the latter case, ERRNO indicates the problem. In the child,
PROCINFO["pid"] and PROCINFO["ppid"] are updated to reflect the correct values.

waitpid()
This function takes a numeric argument, which is the process-id to wait for. The return value is that of the wait-
pid(2) system call.

wait() This function waits for the first child to die. The return value is that of the wait(2) system call.

参考:https://www.cnblogs.com/anker/p/3271773.html