僵尸线程僵尸线程

50 篇文章 4 订阅

在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等.但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等),直到父进程通过wait / waitpid来取时才释放,此时该进程便成为僵尸进程。

1.什么是僵尸进程?
    UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,而父进程还没有结束,那么他将变成一个僵尸进程.
    如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程,因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init来接管他,成为他的父进程,从而保证每个进程都会有一个父进程.而Init进程会自动wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程.

2.子进程结束后为什么要进入僵尸状态?
    因为父进程可能要取得子进程的退出状态等信息。

3.僵尸状态是每个子进程比经过的状态吗?
    是的。任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个 子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。
    如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。

4.如何查看僵尸进程:
    $ ps -el 

    其中,有标记为Z的进程就是僵尸进程
    S代表休眠状态;D代表不可中断的休眠状态;R代表运行状态;Z代表僵死状态;T代表停止或跟踪状态

5.僵尸进程的避免
    1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起
    2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后,父进程会收到该信号,可以在handler中调用wait回收
    3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号

    4. 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收还要自己做。

在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等.但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等),直到父进程通过wait / waitpid来取时才释放,此时该进程便成为僵尸进程。

 
  1. #include "apue.h"

  2. #include <sys/wait.h>

  3. int main(void)

  4. {

  5. pid_t pid;

  6. if ((pid = fork()) < 0)

  7. {

  8. err_sys("fork error");

  9. }

  10. else if (pid == 0)

  11. {

  12. /**//* first child */

  13. if ((pid = fork()) < 0)

  14. err_sys("fork error");

  15. else if (pid > 0)

  16. exit(0);

  17. /**//* parent from second fork == first child */

  18. /**//*

  19. * We're the second child; our parent becomes init as soon

  20. * as our real parent calls exit() in the statement above.

  21. * Here's where we'd continue executing, knowing that when

  22. * we're done, init will reap our status.

  23. */

  24. sleep(2);

  25. printf("second child, parent pid = %d ", getppid());

  26. exit(0);

  27. }

  28. if (waitpid(pid, NULL, 0) != pid) /**//* wait for first child */

  29. err_sys("waitpid error");

  30. /**//*

  31. * We're the parent (the original process); we continue executing,

  32. * knowing that we're not the parent of the second child.

  33. */

  34. exit(0);

  35. }

僵尸线程_随便djy的博客-CSDN博客_僵尸线程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Ubuntu中配置开机自启动程序时,线程状态为僵尸线程是不太可能的情况。僵尸线程是指线程已经结束,但其退出状态还没有被其他线程获取的状态。在Linux中,僵尸线程会被内核自动回收资源,不会一直存在。因此,如果你的线程状态为僵尸线程,可能是由于其他原因导致的。 要配置开机自启动程序,可以使用systemd服务管理器。首先,创建一个.service文件来描述你的程序。在该文件中,指定程序的路径、启动参数等信息。然后,将该文件放置在/etc/systemd/system目录下。最后,使用systemctl命令启用该服务并设置为开机自启动。 以下是一个示例的.service文件内容: ``` \[Unit\] Description=My Program After=network.target \[Service\] ExecStart=/path/to/your/program Restart=always \[Install\] WantedBy=multi-user.target ``` 请将上述示例中的"/path/to/your/program"替换为你实际的程序路径。然后,将该文件保存为myprogram.service,并将其放置在/etc/systemd/system目录下。 接下来,使用以下命令启用该服务并设置为开机自启动: ``` sudo systemctl enable myprogram.service sudo systemctl start myprogram.service ``` 这样,你的程序就会在系统启动时自动运行,并且不会出现僵尸线程的情况。 #### 引用[.reference_title] - *1* *2* *3* [ubuntu下C的多线程的简单实现](https://blog.csdn.net/qq_41167361/article/details/107990763)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值