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小续的更多相关文章

  1. 解决 adb.exe 停止工作小续

    继adb 停止工作的问题之后,又碰见了adb 停止工作的问题. 在使用adb install app.apk 之后给出错误信息如下: * daemon not running. starting it ...

  2. Bitbucket Pull Request和fork

    本文参考了http://blog.jobbole.com/76854/   Pull Request在Forking工作流中使用,这个也同样适用于小团队的开发协作和第三方开发者向开源项目的贡献.当你要 ...

  3. 小程序解决方案 Westore - 组件、纯组件、插件开发

    数据流转 先上一张图看清 Westore 怎么解决小程序数据难以管理和维护的问题: 非纯组件的话,可以直接省去 triggerEvent 的过程,直接修改 store.data 并且 update,形 ...

  4. 1.1 Linux中的进程 --fork、孤儿进程、僵尸进程、文件共享分析

    操作系统经典的三态如下: 1.就绪态 2.等待(阻塞) 3.运行态 其转换状态如下图所示: 操作系统内核中会维护多个队列,将不同状态的进程加入到不同的队列中,其中撤销是进程运行结束后,由内核收回. 以 ...

  5. 三周学会小程序第四讲:Heroku 绑定 Github 自动部署

    这一讲是根据读者的反馈补充的一个讲解,好多读者反应安装 Heroku-cli 遇到问题,或者是操作繁琐,其实上一讲中提到的 Heroku 只是为了免费部署,而安装 Heroku-CLI只是为了部署,所 ...

  6. Git工作流总结

    引用自:https://github.com/xirong/my-git/blob/master/git-workflow-tutorial.md 说明: 个人在学习Git工作流的过程中,从原有的 S ...

  7. Git工作流指南:Pull Request工作流

    参考地址:http://blog.jobbole.com/76854/ Pull Requests是Bitbucket上方便开发者之间协作的功能.提供了一个用户友好的Web界面,在集成提交的变更到正式 ...

  8. [转]深入理解学习GIT工作流

    深入理解学习Git工作流 字数13437 阅读2761 评论3 喜欢70 个人在学习git工作流的过程中,从原有的 SVN 模式很难完全理解git的协作模式,直到有一天我看到了下面的文章,好多遗留在心 ...

  9. printf 缓冲区问题

    突然发现printf的问题,看了这个很有意思,学习一下 转自:http://blog.csdn.net/shanshanpt/article/details/7385649 昨天在做Linux实验的时 ...

随机推荐

  1. new Thread(new ThreadStart(this.StartServer))

    Thread .new thUdpServer thUdpServer = new Thread(new ThreadStart(this.StartServer))

  2. [Angular] Tree shakable provider

    When we create a Service, Angluar CLI will helps us to add: @#Injectable({ providedIn: 'root' }) It ...

  3. ionic在iOS中打包失败

    在ios中打包失败,遇上这样的错误 解决办法,查看index.html的权限是否是只读状态,如果是,改成可读可写,再次打包重试,成功!

  4. Node.js进阶篇-koa、钩子函数、websocket、嵌入式开发

    代码地址如下:http://www.demodashi.com/demo/12932.html 一.简介     koa是由Express原班人马打造的,致力于成为一个更小.更富有表现力.更健壮的We ...

  5. js实现可兼容IE、FF、Chrome、Opera及Safari的音乐播放器

    代码如下: /** 音乐播放器 * @param obj 播放器id * @param file 音频文件 mp3: ogg: * @param loop 是否循环 */ function audio ...

  6. VMware12.0下安装CentOS-6.9-x86_64-bin-DVD.iso

    使用的是vmware workstation 12 pro 创建虚拟机 注意上面的 安装程序光盘镜象文件(iso)(M): 是我之前配置,现在可以不做任何处理 此处使用的是centos的64位 在创建 ...

  7. springboot学习(六) springboot开发web应用

    1.简介 Spring Boot非常适合开发web应用程序.你可以使用内嵌的Tomcat,Jetty或Undertow轻轻松松地创建一个HTTP服务器.大多数的web应用都使用spring-boot- ...

  8. cadence原理图和PCB互联显示成功但是不能高亮和database

    问题现象:cadence原理图和PCB互联显示成功但是不能高亮我的问题 解决:尝试修复数据库试试,Tools->Database check 提醒:有一个封装非法命名,在原理图中修改后 再次保存 ...

  9. php对象序列化总出错false

    php unserialize 返回false的解决方法 php 提供serialize(序列化) 与unserialize(反序列化)方法. 使用serialize序列化后,再使用unseriali ...

  10. 文件打开的过程——调用fd=open()时操作系统所做的工作

    fd=fopen()是一个系统调用.用于依据文件名称打开一个文件.返回该文件的文件描写叙述符,文件打开后进程便能够依据文件描写叙述符fd进行其它操作,比方读,写,关闭等操作. 各个操作系统打开文件的过 ...