My Practical Experience On Linux

Linux 内核相关

僵尸进程

原因

  • 父进程没有回收子进程的资源
  • 子进程的进程描述符仍然存在,因此子进程成为僵尸进程

解决方法

  • 父进程调用 wait() 函数,回收子进程的资源
  • 或者父进程调用 waitpid() 函数,回收子进程的资源
  • 或者父进程调用 signal(SIGCHLD,SIG_IGN) 函数,忽略 SIGCHLD 信号,让内核自动回收子进程的资源

实际开发

当我们在 Linux 主机上遇到占用显存但是找不到对应的进程时(如下图案例所示),往往就是子进程所占用的资源没有被回收,而父进程已经结束。这种情况一般会在多线程并行当中出现,比如在多线程并行训练模型时,如果主线程在子线程结束之前就已经结束,那么子线程就会变成僵尸进程,占用显存。

僵尸进程案例一 僵尸进程案例二

对应的解决方法,一般可以通过检测僵尸进程,然后再寻找僵尸进程对应的父进程,安全地终止父进程后,操作系统就会自动清理对应的子进程。

  • 检测僵尸进程

    1
    ps aux | grep Z

    在输出中,状态列(STAT)会显示为 Z,表示这是一个僵尸进程.

  • 查找僵尸进程对应的父进程

    1
    ps -o ppid= -p 2721429

    可以通过以上命令,查找僵尸进程对应的父进程的 PID,然后进行终止.

  • 终止父进程

    1
    kill -9 2721429

    当父进程被杀死后,操作系统会自动将这些僵尸进程的父进程设置为 init 进程(PID 1),相当于讲这些僵尸进程转移给了 init 进程作为接管的父进程。init 是系统的主进程,它会自动调用 wait() 来回收所有孤立的僵尸进程,从而清除它们。

nohup 后台运行

原理

nohupno hang up 的缩写,它的作用是让进程在后台运行,即使终端关闭也不会影响进程的运行。

使用方法

1
nohup command > output.log 2>&1 &

其中,command 是要执行的命令,output.log 是输出日志文件,2>&1 表示将标准错误输出重定向到标准输出,& 表示将命令放到后台运行。

实际开发

1
nohup sh test.sh > output.log 2>&1 &

以上一条命令,基本能够解决大多数情况下的后台运行。

My Practical Experience On Linux

https://lzhms.github.io/blog/PracticeOnLinux/

Author

Zhihao Li

Posted on

2024-09-23

Updated on

2024-12-24

Licensed under


Comments