为何要使用两次fork?
来源:互联网 发布:印度历史知乎 编辑:程序博客网 时间:2024/05/20 13:11
我们来看看什么事孤儿进程和僵尸进程:
孤儿进程:当子进程还没有结束的时候,其父进程退出,此时此进程就变成了孤儿进程,如图所示:
但是孤儿进程并不会存在很久,当系统发现孤儿进程时,init进程就收养孤儿进程,负责这个孤儿进程exit后的清理工作。
僵尸进程:当子进程在父进程退出前退出的情况下,子进程在从自己退出到父进程退出前的这一段时间是僵尸进程,父进程退出时候,会对这个僵尸进程做清理工作。
当父进程没有用wait回收子进程并不说明它不会回收子进程。子进程结束的时候会给其父进程发送一个SIGCHILD信号,父进程默认是忽略这个信号的,如果父进程通过signal函数设置了SIGCHILD的信号处理函数,则在信号处理函数中可以回收子进程的资源。事实上,即使父进程没有设置处理函数,子进程可以一直保持僵尸状态,当父进程结束后,init进程就会负责回收僵尸子进程。
但是,父进程是一个服务器进程,一直循环不退出,那么子进程一直保持这僵尸状态。虽然僵尸进程不会占用任何内存资源,但是过多的僵尸进程总是会影响系统性能的,这个时候怎么办呢?
两次fork法:
流程如图所示:
int main(int argc,char *argv[]){ //这是一个服务器进程 pid_t pid; if((pid=fork())<0) //服务器创建一个子进程 { cout<<"error"<<endl; }else if(pid==0) { if((pid=fork())<0)//服务器的子进程中再创建一个子进程 { cout<<"error"<<endl; }else if(pid>0) { cout<<"this is a child process of server"<<endl; exit(0);//服务器的子进程退出 }else { cout<<"this is a child process of server's child"<<endl; sleep(10);//为了保证exit退出的时间晚于其父进程 exit(0);//退出后,服务器的子进程已经退出,所以init进程将会接管这个僵尸进程 } }else //pid>0,原始服务器进程 { cout<<"this is server process"<<endl; }}
如何避免僵尸进程?
1.通过signal(SIGCHLD, SIG_IGN)通知内核对子进程的结束不关心,由内核回收。如果不想让父进程挂起,可以在父进程中加入一条语句:signal(SIGCHLD,SIG_IGN);表示父进程忽略SIGCHLD信号,该信号是子进程退出的时候向父进程发送的。
2.父进程调用wait/waitpid等函数等待子进程结束,如果尚无子进程退出wait会导致父进程阻塞。waitpid可以通过传递WNOHANG使父进程不阻塞立即返回。
3.如果父进程很忙可以用signal注册信号处理函数,在信号处理函数调用wait/waitpid等待子进程退出。
通过两次调用fork。父进程首先调用fork创建一个子进程然后waitpid等待子进程退出,子进程再fork一个孙进程后退出。这样子进程退出后会被父进程等待回收,而对于孙子进程其父进程已经退出所以孙进程成为一个孤儿进程,孤儿进程由init进程接管,孙进程结束后,init会等待回收。
第一种方法忽略SIGCHLD信号,这常用于并发服务器的性能的一个技巧因为并发服务器常常fork很多子进程,子进程终结之后需要服务器进程去wait清理资源。如果将此信号的处理方式设为忽略,可让内核把僵尸子进程转交给init进程去处理,省去了大量僵尸进程占用系统资源。
- 为何要使用两次fork?
- 为何要fork()两次来避免产生僵尸进程?
- 为何要fork()两次来避免产生僵尸进程?
- 为何要fork()两次来避免产生僵尸进程?
- 为何要fork()两次来避免产生僵尸进程?
- 为何要fork()两次来避免产生僵尸进程?
- 为何要fork()两次来避免产生僵尸进程?
- 服务器进程为何通常fork()两次
- 服务器进程为何通常fork()两次
- 服务器进程为何通常fork()两次
- 服务器进程为何通常fork()两次
- 服务器进程为何通常fork()两次
- 服务器进程为何通常fork()两次
- 服务器进程为何通常fork()两次
- Daemon进程为何需要两次fork
- 服务器进程为何通常fork()两次
- 服务器进程为何通常fork()两次
- 服务器进程为何通常fork两次(转)
- implements OnClickListener
- 各式各样的正则表达式参考大全
- OpenCV拼图(多种形式,封装,使用,包括图片越界及缩放)
- 鼠标点击右键加入Edit with IDLE
- Sublime Text3 3143,3126 注册码,亲测可用!
- 为何要使用两次fork?
- 数据依赖症:当今AI领域的核心风险
- Emmet (ex-Zen Coding)— the essential toolkit for web-developers
- x的n次幂-LintCode
- Caused by: org.xml.sax.SAXParseException; lineNumber: 33; columnNumber: 23; 元素类型为 "session-factory"
- 文章标题
- centos升级内核步骤
- 程序员如何利用空余时间挣零花钱?
- CSS-列表