首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

不是说父历程wait会给子进程收尸吗?为什么还是僵尸进程

2013-01-02 
不是说父进程wait会给子进程收尸吗?为什么还是僵尸进程?不是说父进程wait会给子进程收尸吗?为什么此时子进

不是说父进程wait会给子进程收尸吗?为什么还是僵尸进程?
不是说父进程wait会给子进程收尸吗?为什么此时子进程还是僵尸进程?

如下代码:


至于出现出入不同,以前在红帽5下也遇到过,可能是内核版本问题

[解决办法]
重启下电脑,或者换个系统,换个电脑试试,
[解决办法]
引用:
引用:重启下电脑,或者换个系统,换个电脑试试,


确实哦。 我换了一个系统,用centos测试了一下,发现就没有那个问题了。

但是两个都是linux,内核都是2.6,小版本不一样。 为什么处理的结果会不一样呢 ?

这个和什么操作系统,内核版本无关。
完全是进程调度和你加的printf造成的时间延时的结果。
[解决办法]
聋子打岔一下:
《Windows编程启示录》
19.6 为什么有些进程在被终止之后还停留在任务管理器中
    当某个进程结束时(可能是正常结束,也可能是因为调用了像TerminateProcess之类的函数),这个进程的用户态模块将被删除。但内核态模块只有在与线程相关的所有驱动程序执行完成之后才会被删除。
    例如,如果某个线程正处于I/O操作中,那么将会给负责I/O的驱动程序发送一个内核信号来取消这个操作。
    如果驱动程序的行为是良好的,那么它将清除与这个未完成I/O相关的一些信息并且释放线程。
    如果驱动程序的行为是不好的(可能是因为驱动程序管理的硬件表现出奇怪的行为),那么可能需要花很长的时间来清除这个未完成的I/O。在这段时间里,驱动程序将不会释放这个线程(以及这个线程所在的进程)。实际的情况要更复杂一些,但这里的简单模型对于我们的讨论已经足够。
   ……
   换句话说,如果你终止了某个进程后还能在任务管理器中看到这个进程,那么实际上这个进程已经停止运行了,只不过还有些残留的信息保留在系统中,只有当与这个进程相关的所有驱动程序都完成了清除操作并且指向这个进程的句柄都已经关闭,进程才会完全消失。

[解决办法]
引用:
引用:LZ的wait()可以编译过?
C/C++ code?123456789101112131415161718192021# include <stdio.h># include <stdlib.h># include <sys/types.h># include <sys/wait.h># include <unistd.h> ……



好吧,LZ的程序我直接拿来编译,然后
cc  -Wall   z.c   -o z
z.c: In function ‘main’:
z.c:6: warning: implicit declaration of function ‘fork’
z.c:14: warning: implicit declaration of function ‘wait’
z.c:16: warning: implicit declaration of function ‘sleep’

当然,它的确过了,不过确实也出现了LZ说的情况,僵了。

然后恳请LZ试试我的程序,反正是没有出现僵的情况的。

大家都讨论问题么,所以……

[解决办法]
引用:
引用:先看19L

说说我的想法吧:这是典型的“勿以恶小而为之”。

正确的包含头文件,以及重视编译器的warning,是所谓的“素质”。

由于LZ没有包含头文件,编译器也无法做出编译时检查,只能给出warning;而对于warning,LZ又视而不见。

问题在哪里呢?显然wait是需要一个参数的,由于就这么过了,程……

楼主不要眼高手低,别人指出你的错误就虚心接受。
编译的时候加个 -Wall参数试试,看看有没有warning。我看你传的图片编译参数没加 -Wall
你认为wait()和wait(NULL)是一回事吗?


[解决办法]
1、为什么我不包含sys/wait.h仍然能够编译过去?
    我知道我想要的wait的原型是在这里: sys/wait.h: extern __pid_t __wait (__WAIT_STATUS __stat_loc);
    但是我始终找不到wait(void)的原型,这也就是我始终困惑的地方。应该是在stdio.h或者stdlib.h的某个地方有wait(void)的声明。这就是为什么加上sys/wait.h 就编译不过,但是不加就能够编译的原因吧。 关于这一点麻烦shimachao帮忙解释一下。

// 注意,压根就没有wait(void)的原型,哪里都没有
// 加上头文件编译不过是因为编译器根据原型作出了调用检查,不加能编译过是编译器不能做检查,只好忽略,但是,记得,它有warning

2、按照shimachao说的,wait用作于父进程等待子进程的时候应该加上参数,那么我不加参数到底会怎么样? 不知道你是否知道这一点?为什么我在centos上使用wait(void)也能实现wait(int* __stat_loc)一样的功能?

// 回去看看我21L的解答,不加参数,又编译过了,所以生成的是个错误的调用,它的参数是从栈上错误的位置得到的,如果是个错误的参数,最后有什么,只能把所有的相关的实现都看过了,才能得知;
// 一个环境可以,另一个环境不行,可以大胆猜测,两个环境栈上的内容不尽相同,一个阴错阳差,收尸了,一个搞不定,收不了尸;用debugger,能很容易的看栈上的内容

3、我在编译的时候本来就没有遇见waining,怎么可能叫做熟视无睹哈?! 虽然加上-Wall会看到warning,但是一般我编译的时候都不加那个参数的,太罗嗦了。

// 所以必须加上-Wall,养成好习惯
// 是以“勿以恶小而为之”

4、倒是在内核源码里面发现了wait(void)的代码,不过不知道是不是我调用的那个:

// 不是,没记错的话__sys_wait(...)才是

热点排行