fork小续
pid_t pid = fork();
1.根据fork的返回值区分父子进程:
fork 函数返回两次, >0 表示父进程,返回值为子进程ID; =0 表示子进程; <0 出错。
可用代码表示为:
if( ( pid = fork() ) < ){
//error
}
else if( pid == ){
//child
}
else{
//parent
}
2.进程调用wait等待子进程的退出:
系统调用wait做两件事:a.wait暂停调用它的进程直到子进程结束;b.wait取得子进程结束时传给exit的值。
系统调用wait的两个特征:a.wait阻塞调用它的进程直到子进程结束;b.wait返回结束进程的PID。
父进程必须要回收子进程,这时必须用wait/waitpid。不然当子进程结束后,它会变成僵死进程。用"ps -ef"命令查看,可看到其状态为<defunct>。所以,在fork()之后,我们一般执行:waitpid(pid,NUL,0);
参数1: pid表示到等待的子进程ID
参数2: NULL表示对子进程的结束状态不在意。
参数3: 控制选项
if( ( pid = fork() ) < ){
//error
}
else if( pid == ){
//child
...
}
else{
waitpid( pid, NULL, ); //用于等待子进程结束.
}
3. 问题提出——父进程被阻塞:
在调用waitpid后,父进程被阻塞,将不能执行其他的任务,这在监听程序中是不允许的。所以,必须要回收掉子进程,并且父进程不能被阻塞,要解决这个问题,我们可以fork两次,让子进程被init进程托管。
if( ( pid = fork() ) < ){
//error
}
else if( pid == ){
//first child exit !
if( fork() > ){
exit();
}
else{
//second child...
}
}
else{
waitpid( pid, NULL, );
//因为第一个子进程马上退出,所以waitpid在等到其结束时马上返回,第二
//个子进程将被init进程托管!
}
4.问题提升——子进程结束标志:
我们让子进程被init进程托管,也就等于对它放弃了控制权,没办法知道它什么时候结束的,以及结束的状态是什么。所以,为了父进程不被阻塞,并且能够及时的回收掉子进程。这时,用信号是个不错的选择。
int chld_count = ; void sigchd_exit(int signo)
{
if( waitpid(-, NULL, WNOHANG) > ) chld_count--; printf( "child count: %d\n", chld_count );
} void set_sigchd()
{
signal(SIGCHLD, sigchd_exit); //子程序退出的信号
signal(SIGINT, sigchd_exit); //Ctrl+C
signal(SIGTERM, sigchd_exit);
} //.....
set_sigchd()
if( ( pid = fork() ) < ){
//error
}
else if( pid == ){
//child
...
}
else{
chld_count++;
}
这时,在程序开始时设置信号处理函数,当子进程结束时,信号处理函数回收子进程,减少子进程计数。fork之后,父进程增加子进程计数。这样子,程序就实时的知道了子进程的个数。也就可以对止之后的fork做出一定的限制。
fork小续的更多相关文章
- 解决 adb.exe 停止工作小续
继adb 停止工作的问题之后,又碰见了adb 停止工作的问题. 在使用adb install app.apk 之后给出错误信息如下: * daemon not running. starting it ...
- Bitbucket Pull Request和fork
本文参考了http://blog.jobbole.com/76854/ Pull Request在Forking工作流中使用,这个也同样适用于小团队的开发协作和第三方开发者向开源项目的贡献.当你要 ...
- 小程序解决方案 Westore - 组件、纯组件、插件开发
数据流转 先上一张图看清 Westore 怎么解决小程序数据难以管理和维护的问题: 非纯组件的话,可以直接省去 triggerEvent 的过程,直接修改 store.data 并且 update,形 ...
- 1.1 Linux中的进程 --fork、孤儿进程、僵尸进程、文件共享分析
操作系统经典的三态如下: 1.就绪态 2.等待(阻塞) 3.运行态 其转换状态如下图所示: 操作系统内核中会维护多个队列,将不同状态的进程加入到不同的队列中,其中撤销是进程运行结束后,由内核收回. 以 ...
- 三周学会小程序第四讲:Heroku 绑定 Github 自动部署
这一讲是根据读者的反馈补充的一个讲解,好多读者反应安装 Heroku-cli 遇到问题,或者是操作繁琐,其实上一讲中提到的 Heroku 只是为了免费部署,而安装 Heroku-CLI只是为了部署,所 ...
- Git工作流总结
引用自:https://github.com/xirong/my-git/blob/master/git-workflow-tutorial.md 说明: 个人在学习Git工作流的过程中,从原有的 S ...
- Git工作流指南:Pull Request工作流
参考地址:http://blog.jobbole.com/76854/ Pull Requests是Bitbucket上方便开发者之间协作的功能.提供了一个用户友好的Web界面,在集成提交的变更到正式 ...
- [转]深入理解学习GIT工作流
深入理解学习Git工作流 字数13437 阅读2761 评论3 喜欢70 个人在学习git工作流的过程中,从原有的 SVN 模式很难完全理解git的协作模式,直到有一天我看到了下面的文章,好多遗留在心 ...
- printf 缓冲区问题
突然发现printf的问题,看了这个很有意思,学习一下 转自:http://blog.csdn.net/shanshanpt/article/details/7385649 昨天在做Linux实验的时 ...
随机推荐
- [Spring boot] Integrating with h2 database
In pom.xml add dependency: <dependencies> <dependency> <groupId>org.springframewor ...
- 【Android高级】应用开发必需要掌握的框架<Volley>
开发久了,就会发现掌握一个好的应用框架是多么的重要,尽管是别人的东西,你或许不能全然搞懂当中的原理,但你知道怎样利用其到自己的开发中,这样不仅能节省大量的时间.并且别人沉淀下来的精华效果一定比他的厉害 ...
- Oracle数据类型,函数与存储过程
字符串类型 固定长度:char nchar n 表示Unicode编码 可变长度: varchar2 nvarchar2 数字类型:number(P,S)P:整数位数,S小数位数 ...
- Zend Framework(一) windows8.1下配置zend framework1.12
windows8.1下配置zend framework1.12配置步骤: 1. 下载 zend framework1.12库 2. 创建zend frameworkproject 2 ...
- LInux——安装Apache
在安装Apache的httpd的时候经常会遇到: configure: error: APR not found . Please read the documentation. configure ...
- ajax请求web容器控制超时
1.项目用到超时控制,针对ajax请求超时,可以参照如下解决方案 tomcat容器 web.xml 中配置 <session-config> <session-timeout> ...
- 通过xsd schema结构来验证xml是否合法
import sys import StringIO import lxml from lxml import etree from StringIO import StringIO # Constr ...
- 将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1
主要升级步骤如下: 将 .csproj 项目文件中的 target framework 改为 netcoreapp2.1 <TargetFramework>netcoreapp2.1< ...
- C语言基础(19)-结构体,联合体,枚举和typedef
一.结构体 1.1 结构体struct定义及初始化 #include <stdio.h> // 这个头文件在系统目录下 #include <stdlib.h> // 使用了sy ...
- linux下调试使用的 一些shell命令
查看文件日期:strings |grep Build gdb g++ gcc make systemctl gdb: bt s n b 1.firewalld的基本使用 启动: systemctl s ...