linux wait()函数

linux wait()函数


2024年5月11日发(作者:)

在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,

那么他将变成一个僵尸进程. 但是如果该进程的父进程已经先结束了,那么该进程就不会变

成僵尸进程, 因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程, 看有

没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init 来接管他,成为他的父

进程……

一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁, 而

是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是 使进程退

出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)

2. 僵尸进程的危害

由于子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到

底什么时候结束. 那么不会因为父进程太忙来不及waid子进程,或者说不知道 子进程什么

时候结束,而丢失子进程结束时的状态信息呢? 不会.因为UNIX提供了一种机制可以保证

只要父进程想知道子进程结束时的状态信息, 就可以得到. 这种机制就是: 在每个进程退

出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等. 但是仍然为其保留

一定的信息(包括进程号the process ID,退出状态the termination status of the process,

运行时间the amount of CPU time taken by the process等), 直到父进程通过wait /

waitpid来取时才释放. 但这样就导致了问题,如果你进程不调用wait / waitpid的话, 那么

保留的那段信息就不会 释放,其进程号就会一定被占用,但是系统所能使用的进程号是有限

的,如果大量的产生 僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此

即为僵尸进程的危害,应当避免.

3.僵尸进程的避免

1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起

2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程

结束后, 父进程会收到该信号,可以在handler中调用wait回收

3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN)

通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父

进程发送信号

4. 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程

fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进

程的回收 还要自己做。 下面就是Stevens给的采用两次folk避免僵尸进程的示例.

3、僵尸进程的处理: 它需要它的父进程来为它收尸,如果他的父进程没安装SIGCHLD

信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就

一直保持僵尸状态; 存在的问题:如果父进程是一个循环,不会结束,那么子进程就会一

直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程,系统的性能可能会收到

影响。 ** 如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它

还是能被清除的。 4、子进程结束后为什么要进入僵尸状态? * 因为父进程可能要取得子

进程的退出状态等信息。 5、僵尸状态是每个子进程比经过的状态吗? 是的。 * 任何一

个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)

的数据结构,等待父进程处理。这是每个 子进程在结束时都要经过的阶段。如果子进程在

exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果

父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进

程不经过僵尸状态。 * 如果父进程在子进程结束之前退出,则子进程将由init接管。init


发布者:admin,转转请注明出处:http://www.yc00.com/news/1715388236a2610515.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信