fork()函数的执行过程、孤儿进程和僵尸进程
说起fork就不得不提COW(Copy On Write),就是“写时拷贝”。也就是当fork发生时,子进程根本不会去拷贝父进程的内存页面,而是与父进程共享。当子进程或父进程需要修改一个内存页面时,Linux就将这个内存页面复制一份给修改者,然后再去修改,这样从用户的角度看,父子进程根本就没有共享什么内存。COW也就是进程要写共享的内存页面,先复制再改写。
采用了COW技术后,fork时,子进程还需要拷贝父进程的页面表。这种拷贝的代价就非常小了,对于CPU来说用不了几个时钟周期。
1.孤儿进程
孤儿进程:就是没有父进程的进程。一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
2.僵尸进程
僵尸进程:一个子进程在其父进程还没有调用wait()或waitpid()的情况下退出。这个子进程就是僵尸进程。
3.危害
僵尸进程会占用系统资源,如果很多,则会严重影响服务器的性能
孤儿进程不会占用系统资源,最终是由init进程托管,由init进程来释放它。
处理流程:
只要老爹不等wait(sys/wait.h)儿子,儿子都将成为孤魂野鬼zombie(zombie),unix中默认老爹总是想看儿子死后的状态(以便报仇)
if 老爹比儿子先再见
儿子将被init(id = 1)收养,最后的结果是zombie儿子彻底再见,系统资源释放
else
{
儿子的zombie将一直存在,系统资源占用...
if 老爹dead
儿子将被init(id = 1)收养,最后的结果是zombie儿子彻底再见,系统资源释放
else 类似的儿子zombie越来越多,系统就等死了!!!
}
signal(SIGCHLD, SIG_IGN); //忽略SIGCHLD信号,这常用于并发服务器的性能的一个技巧
//因为并发服务器常常fork很多子进程,子进程终结之后需要
//服务器进程去wait清理资源。如果将此信号的处理方式设为
//忽略,可让内核把僵尸子进程转交给init进程去处理,省去了
//大量僵尸进程占用系统资源。(Linux Only)
4.如何防止僵尸进程
首先明白如何产生僵尸进程:
1、子进程结束后向父进程发出SIGCHLD信号,父进程默认忽略了它
2、父进程没有调用wait()或waitpid()函数来等待子进程的结束
第一种方法: 捕捉SIGCHLD信号,并在信号处理函数里面调用wait函数
转贴Richard Steven的Unix Network Programming代码
int
main(int argc, char **argv)
{
...
Signal(SIGCHLD, sig_chld);
for(;
}
...
}
void
sig_chld(int signo)
{
pid_t pid;
int stat;
while ( (pid = waitpid(-1, &stat, WNOHANG)) >; 0)
printf("child %d terminated/n", pid);
return;
}
第二种方法:两次fork():转载
在《Unix 环境高级编程》里关于这个在8.6节有非常清楚的说明。
实例
回忆一下8 . 5节中有关僵死进程的讨论。如果一个进程要fork一个子进程,但不要求它等待
子进程终止,也不希望子进程处于僵死状态直到父进程终止,实现这一要求的诀窍是调用f o r k
两次。程序8 - 5实现了这一点。
在第二个子进程中调用s l e e p以保证在打印父进程I D时第一个子进程已终止。在f o r k之后,
父、子进程都可继续执行——我们无法预知哪一个会先执行。如果不使第二个子进程睡眠,则
在f o r k之后,它可能比其父进程先执行,于是它打印的父进程I D将是创建它的父进程,而不是
i n i t进程(进程ID 1)。
#include <sys/types.h>
#include <sys/wait.h>
#include "ourhdr.h"
int main(void)
{
pid_t pid;
if ( (pid = fork()) < 0)
err_sys("fork error");
else if (pid == 0) { /* first child */
if ( (pid = fork()) < 0)
err_sys("fork error");
else if (pid > 0)
exit(0); /* parent from second fork == first child */
/* We're the second child; our parent becomes init as soon
as our real parent calls exit() in the statement above.
Here's where we'd continue executing, knowing that when
we're done, init will reap our status. */
sleep(2);
printf("second child, parent pid = %d/n", getppid());
exit(0);
}
if (waitpid(pid, NULL, 0) != pid) /* wait for first child */
err_sys("waitpid error");
/* We're the parent (the original process); we continue executing,
knowing that we're not the parent of the second child. */
exit(0);
}
fork()函数的执行过程、孤儿进程和僵尸进程的更多相关文章
- 1.1 Linux中的进程 --fork、孤儿进程、僵尸进程、文件共享分析
操作系统经典的三态如下: 1.就绪态 2.等待(阻塞) 3.运行态 其转换状态如下图所示: 操作系统内核中会维护多个队列,将不同状态的进程加入到不同的队列中,其中撤销是进程运行结束后,由内核收回. 以 ...
- linux系统编程之进程(三):进程复制fork,孤儿进程,僵尸进程
本节目标: 复制进程映像 fork系统调用 孤儿进程.僵尸进程 写时复制 一,进程复制(或产生) 使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:进程上下文.进程堆栈. ...
- wait函数返回值总结,孤儿进程与僵尸进程[总结]
http://blog.csdn.net/astrotycoon/article/details/41172389 wait函数返回值总结 http://www.cnblogs.com/Anker/p ...
- PHP7 网络编程(三)孤儿进程与僵尸进程
基本概念 我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程.子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束. 当一个 ...
- python学习笔记—— 多进程中的 孤儿进程和僵尸进程
1 基本概述 1.1 孤儿进程和僵尸进程 父进程创建子进程后,较为理想状态是子进程结束,父进程回收子进程并释放子进程占有的资源:而实际上,父子进程是异步过程,两者谁先结束是无顺的,一般可以通过父进程调 ...
- 什么是PHP7中的孤儿进程与僵尸进程
什么是PHP7中的孤儿进程与僵尸进程 基本概念 我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程在创建新的进程.子进程的结束和父进程的运行是一个异步过程,即父进程永远无法 ...
- 并发编程(二)--利用Process类开启进程、僵尸进程、孤儿进程、守护进程、互斥锁、队列与管道
一.multiprocessing模块 1.multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似. 2.mu ...
- 并发编程(二)——利用Process类开启进程、僵尸进程、孤儿进程、守护进程、互斥锁、队列与管道
Process类与开启进程.守护进程.互斥锁 一.multiprocessing模块 1.multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模 ...
- [Linux] 孤儿进程与僵尸进程[总结]
转载: http://www.cnblogs.com/Anker/p/3271773.html 1.前言 之前在看<unix环境高级编程>第八章进程时候,提到孤儿进程和僵尸进程,一直对这两 ...
- 020_Linux的孤儿进程与僵尸进程(Unix系统编程)
1.前言 之前在看<unix环境高级编程>第八章进程时候,提到孤儿进程和僵尸进程,一直对这两个概念比较模糊.今天被人问到什么是孤儿进程和僵尸进程,会带来什么问题,怎么解决,我只停留在概念上 ...
随机推荐
- 一句话懂什么是JS闭包
无论何时声明新函数并将其赋值给变量,都要存储函数定义和闭包.闭包包含在函数创建时作用域中的所有变量,它类似于背包.函数定义附带一个小背包,它的包中存储了函数定义创建时作用域中的所有变量. 我将永远记住 ...
- json转换为字典
str---dict ata_dict=json.loads(data)
- Fedora 28 系统基础配置以及常用软件安装方式
实验说明: 很多人说Linux很难用,很难上手,其实不然,倘若不玩游戏,其实很多发行版Linux都可以成为主力系统,就比如本章要讲的 Fedora 28.本章会从镜像来源.系统安装.基础配置和常用软件 ...
- 模拟发送http请求的工具推荐
做网站开发时,经常需要发送请求来测试自己的代码是否OK,这时候模拟发送http请求的工具就起到了很大的作用.特别是需要在请求带header时就更加的有必要使用工具.下面推荐的工具有的是基于系统开发的程 ...
- css3属性:美化表单、点击元素产生的背景与边框怎么去掉,滚动回弹效果
- Win2008 Server配置PHP环境
Win2008 Server配置PHP环境 阅读目录 创建一个网站 配置PHP环境 配置iis的“处理应用程序映射” 在配置PHP环境之前要先配置好IIS. 传送门-> Win2008 Se ...
- 第6章 AOP与全局异常处理6.5-6.11 慕课网微信小程序开发学习笔记
https://coding.imooc.com/learn/list/97.html 目录: 第6章 AOP与全局异常处理6-1 正确理解异常处理流程 13:236-2 固有的处理异常的思维模式与流 ...
- 【python学习】新手基础程序练习(一)
首先得先编一下程序员必须编的程序——Hello World……(这应该是程序员情结...) #coding=utf-8 #Version:python3.7.0 #Tools:Pycharm 2017 ...
- Python头脑风暴3
驾校是个暴利行业 如果有高学历靠谱的IT人员做驾校教练等等等等.... Python虽然难做企业级应用,但Python是全球个人自定义应用的首选!!!没有之一,所有语言最快的开发速度,最个性化的私人定 ...
- LeetCode(205)Isomorphic Strings
题目 Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the ch ...