僵尸进程介绍_僵尸进程的危害

僵尸进程介绍_僵尸进程的危害进程的生命周期进程在它被创建的时刻开始存活,在linux系统中,这通常是调用fork()系统调用的结果,该系统调用通过复制一个现有进程来创建一个全新的进程。调用fork()的进程被称为父进程,新产生的进程被称为子进程。在该调用结束时,在返回点这个相同位置上,父进程恢复执行,子进程开始执行。fork()系统调用从内核返回两次:一次回到父进程,另一次回到新诞生的子进程。通常,创建新的进程都是为了立即执行新的、不同的程序,而接着调用exec*()这族函数就可以创建新的地址空间,并把新的程序载

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

进程的生命周期

进程在它被创建的时刻开始存活,在 linux 系统中,这通常是调用 fork() 系统调用的结果,该系统调用通过复制一个现有进程来创建一个全新的进程。调用 fork() 的进程被称为父进程,新产生的进程被称为子进程。在该调用结束时,在返回点这个相同位置上,父进程恢复执行,子进程开始执行。fork() 系统调用从内核返回两次:一次回到父进程,另一次回到新诞生的子进程。
通常,创建新的进程都是为了立即执行新的、不同的程序,而接着调用 exec*() 这族函数就可以创建新的地址空间,并把新的程序载入。
最终,程序通过 exit() 系统调用退出执行。这个函数会终结进程并将其占用的资源释放掉。父进程可以通过 wait4() 系统调用查询子进程是否终结,这其实使得进程拥有了等待特定进程执行完毕的能力。进程退出执行后被设置为僵死状态,直到它的父进程调用 wait() 或 waitpid() 为止。

再谈僵尸进程

一个进程在调用 exit 命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(zombie)的数据结构(系统调用 exit(),它的作用是使进程退出,但它仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。
在 linux 进程的状态中,僵尸进程使非常特殊的一种,它已经放弃了几乎所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间(如《写一个僵尸进程》这篇文章最后通过 ps 查看的状态一样,僵尸进程的 VSZ RSS 均为 0)。它需要它的父进程来为它收尸,如果它的父进程没有安装 SIGCHLD 信号处理函数调用 wait() 或 waitpid() 等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态,如果这时父进程结束了,那么 init 进程自动接手这个子进程,为它收尸,它还是能被清除的。但是如果父进程是一个死循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多僵尸进程的原因。
在UNIX 系统中,一个进程结束了,但是它的父进程没有等待(调用 wait() / waitpid())它, 那么它将变成一个僵尸进程. 在 fork()/execve() 过程中,假设子进程结束时父进程仍存在,而父进程 fork() 之前既没安装SIGCHLD 信号处理函数调用 waitpid() 等待子进程结束,又没有显式忽略该信号,则子进程成为僵尸进程。
因此,一个僵尸进程产生的过程是:父进程调用 fork() 创建子进程后,子进程运行直至其终止,它立即从内存中移除,但进程描述符仍然保留在内存中(进程描述符占有极少的内存空间)。子进程的状态变成 EXIT_ZOMBIE,并且向父进程发送 SIGCHLD 信号,父进程此时应该调用 wait() 系 统调用来获取子进程的退出状态以及其它的信息。在 wait() 调用之后,僵尸进程就完全从内存中移除。因此一个僵尸进程存在于其终止到父进程调用 wait() 等函数这个时间的间隙,一般很快就消失,但如果编程不合理,父进程从不调用 wait() 等系统调用来收集僵尸进程,那么这些进程会一直存在内存中。

怎样来清除僵尸进程

  1. 改写父进程,在子进程结束后为它收尸。具体做法是接管SIGCHLD信号。子进程死后,会发送SIGCHLD信号给父进程,父进程收到此信号后,执 行waitpid()函数为子进程收尸。
  2. 把父进程杀掉。父进程死后,僵尸进程成为“孤儿进程”,过继给 1 号进程 init,init 始终会负责清理僵尸进程,它产生的所有僵尸进程也跟着消失。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/213667.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java 线程死锁及如何避免死锁介绍

    Java 线程死锁及如何避免死锁介绍死锁是指两个或两个以上的线程在执行过程中,**因争夺资源而造成的互相等待**的现象,在无外力作用的情况下,这些线程会一直相互等待而无法继续运行下去,

    2022年7月13日
    12
  • android之java程序性能优化(不断补充)

    在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身。养成良好的编码习惯非常重要,能够显著地提升程序性能。一、避免在循环条件中使用复杂表达式在不做编译优化的情况下,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快。还有一个原则,决不在一个For语句中第二次调用一个类的方法例子: class cel

    2022年3月9日
    53
  • Eclipse中Editor does not contain a main type 解决方法

    Eclipse中Editor does not contain a main type 解决方法Eclipse中Editordoesnotcontainamaintype解决方法1、问题再现2、原因当前的源代码(所有的包)没有被添加到buildpath中src目录出现错误3、解决方法…

    2022年6月1日
    57
  • Mysql8.0以上重置初始密码的方法[通俗易懂]

    Mysql8.0以上重置初始密码的方法[通俗易懂]Mysql8.0以上忘记初始密码时重置的方法摘要第一步:关闭Mysql服务第二步:跳过Mysql密码验证第三步:无密码方式进入Mysql第四步:将登陆密码设置为空第五步:更改自己的登陆密码最后一步:验证密码是否修改成功摘要网上大部分的方法都是通过在My.ini或是My_default.ini中添加–skip-grant-tables的方法来实现跳过Mysql密码来连接数据库,并更改密码。我花…

    2022年5月31日
    33
  • H2 数据库使用简介

    一、前言H2是一个用Java开发的嵌入式数据库,它本身只是一个类库,即只有一个jar文件,可以直接嵌入到应用项目中。H2主要有如下三个用途:第一个用途,也是最常使用的用途就在于可以同应用程序打包在一起发布,这样可以非常方便地存储少量结构化数据。第二个用途是用于单元测试。启动速度快,而且可以关闭持久化功能,每一个用例执行完随即还原到初始状态。第三个用途是作为缓存,即当做内…

    2022年4月7日
    231
  • anycast技术「建议收藏」

    anycast技术「建议收藏」转载别人的,不好意思啊浅析AnyCast网络技术什么是BGPAnyCast?BGPanycast就是利用一个(多个)as号码在不同的地区广播相同的一个ip段。利用bgp的寻路原则,短的aspath会选成最优路径(bgp寻路原则之n),从而优化了访问速度。其实bgpanycast是不同服务器用了相同的ip地址。阿里的DNS就是使用了BGPAn…

    2022年5月10日
    49

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号