僵尸进程、孤儿进程、守护进程

一. 什么是僵尸进程? 危害? 避免僵尸进程的方式?

  • 僵尸进程: 一个进程使用 fork 创建出子进程,如果子进程退出而父进程并没有读取到子进程退出的返回代码,那么子进程就会以终止状态保持在状态表中,处在这种状态下的进程就是僵尸进程。

  • 产生僵尸进程的原因:

    • 父进程没有调用 wait 或 waitpid 函数来等待子进程结束。
    • 子进程结束后向父进程发出的 sigchld(c扣d) 信号,父进程没有收到或者忽略了。
  • 如何避免僵尸进程:

    • 使用 signal 函数显式忽略 sigchld 子进程终止信号,这样子进程结束后就不会给父进程发送信号,而是直接由内核来回收。
    • 父进程调用 wait 或 waitpid 函数来等待子进程结束。(wait 函数的缺点是,如果没有子进程终止,那么程序会被阻塞,需要慎用)
    • fork 两次:父进程 fork 一个子进程,子进程再 fork 一个孙进程,然后子进程退出,孙进程被 init 进程接管,这样孙进程结束后就会由 init 进程回收了。
  • 僵尸进程的危害: 占用了系统内存,而且过多的话可能会引起内存泄漏。

二. 什么是孤儿进程?

  • 孤儿进程: 父进程退出后,它的子进程还在运行,那么子进程就会成为孤儿进程。孤儿进程将被 init 进程收养,并由 init 进程对它们完成状态收集工作,孤儿进程并不会占用系统内存。

三. 什么是守护进程?如何创建守护进程

  • 守护进程: 也就是 Daemon(低men) 进程,指在后台运行且不受终端控制的进程,比如有系统日志进程 syslogd、数据库服务器进程 mysqld,都是以字母 d 结尾的。设置守护线程的方法:线程名.setDaemon(true);
  • 如何创建守护进程: 分为六步
  1. fork 创建子进程,父进程 exit 退出。此时子进程就变为孤儿进程,并由 init 进程收养。
  2. 子进程调用 setsid 函数创建新会话。使当前进程脱离原会话、原进程组和原控制终端的控制,让进程真正独立出来。
  3. 再次 fork 出一个子进程并让父进程 exit 退出。这样进程就不再是会话首进程了,于是禁止了进程重新打开控制终端。
  4. 在子进程中调用 chdir 函数,让根目录" / "成为子进程的工作目录。避免了和原来的父进程目录一样所带来的问题。
  5. 在子进程中调用 umask 函数,设置文件权限码为0。
  6. 在子进程中 close 不需要的文件描述符。
发布了307 篇原创文章 · 获赞 11 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/dl674756321/article/details/103551671