转载:https://blog.csdn.net/qq_28840229/article/details/79844763

fork之后:

父子相同处: 全局变量、.data、.text、栈、堆、环境变量、用户ID、宿主目录、进程工作目录、信号处理方式...

父子不同处: 1.进程ID   2.fork返回值   3.父进程ID    4.进程运行时间    5.闹钟(定时器)   6.未决信号集

似乎,子进程复制了父进程0-3G用户空间内容,以及父进程的PCB,但pid不同。真的每fork一个子进程都要将父进程的0-3G地址空间完全拷贝一份,然后在映射至物理内存吗?

当然不是!父子进程间遵循读时共享写时复制的原则。这样设计,无论子进程执行父进程的逻辑还是执行自己的逻辑都能节省内存开销。

1、fork函数时调用一次,返回两次。在父进程和子进程中各调用一次。子进程中返回值为0,父进程中返回值为子进程的PID。程序员可以根据返回值的不同让父进程和子进程执行不同的代码。子进程是父进程的副本,获得了父进程数据空间、堆和栈的副本;父子进程并不共享这些存储空间,共享正文段(即代码段);因此子进程对变量的所做的改变并不会影响父进程。一般来说,fork之后父、子进程执行顺序是不确定的,这取决于内核调度算法。进程之间实现同步需要进行进程通信。

子进程对数据进行减一操作,父进程做加一操作:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
 
int main()
{
 pid_t pid;
 char *message;
 int n = 0;
 pid = fork();
 while(1){
 if(pid < 0){
 perror("fork failed\n");
 exit(1);
 }
 else if(pid == 0){
 n--;
 printf("child's n is:%d\n",n);
 }
 else{
 n++;
 printf("parent's n is:%d\n",n);
 }
 sleep(1);
 }
 exit(0);
}

2、进程等待

孤儿进程: 父进程生成子进程,但是父进程比子进程先结束;子进程会变成孤儿进程,由系统1号init 进程进行接管。init 进程接管后,在该孤儿进程结束的时候,负责“收尸”,回收系统资源及进程信息。

僵尸进程:子进程已经退出,但是没有父进程回收它的资源(父进程生成的子进程,但是子进程比父进程先挂掉,如果父进程没有收回它的资源时,那么子进程挂掉后就变成了僵尸进程;应该尽量避免产生僵尸进程,可以在父进程调用wait 或者waitpid 进程回收)。

进程一旦调用了wait,就立即阻塞自己,由wait 自动分析是否当前进程的某个子进程已经退出。如果让它找到了这样一个已经变成僵尸的子进程,wait 就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait 就会一直阻塞在这里,直到有一个出现为止。

补充:

进程0

内核是一个大的程序,可以控制硬件,也可以创建、运行、终止、控制所有的进程。当内核被加载到内存后,首先就会有完成内核初始化的函数start_kernel()从无到有的创建一个内核线程swap,并设置其PID为0,即进程0;它也叫闲逛进程;进程0执行的是cpu_idle()函数,该函数仅有一条hlt汇编指令,就是在系统闲置时用来降低电力的使用和减少热的产生。同时进程0的PCB叫做init_task,在很多链表中起了表头的作用。

当就绪队列中再没有其他进程时,闲逛进程就会被调度程序选中,以此来省电,减少热量的产生。

进程1

即init进程。首先内核线程kernel_init执行内核的一些初始化函数,以将内核初始化。那么此内核态的线程又是怎样变为一个用户进程的?实际上,kernel_int()内核函数中调用了execve()系统调用,该系统调用装入用户态下的一个可执行程序init,从而启动用户进程init进程。注意,内核函数kernel_init()与用户态下的可执行文件init是不同的,位置不同,运行状态不同,代码也不同。init进程只是内核线程kernel_init启动起来的一个普通的用户进程,当然也是用户态下的第一个进程,并且init进程从不终止,用来创建和监控操作系统外层的所有进程的活动。

3、父进程创建多个子进程问题

void createsubprocess(int num)  
{  
    pid_t pid;  
    int i;  
    for(i=0;i<num;i++)  
    {  
        pid=fork();  
        if(pid==0||pid==-1)  //子进程或创建进程失败均退出,这里是关键所在,子进程中跳出循环。
        {  
            break;  
        }  
    }  
    if(pid==-1)  
    {  
        perror("fail to fork!\n");  
        exit(1);  
    }  
    else if(pid==0)  
    {  
        printf("子进程id=%d,其对应的父进程id=%d\n",getpid(),getppid());  
        exit(0);  
    }  
    else 
    {  
        printf("父进程id=%d\n",getpid());  
        exit(0);  
    }  
}

进程之父子进程的关系相关推荐

  1. 【Linux】进程概念——父子进程、僵尸进程和孤儿进程

    目录 父子进程 什么是父子进程? ==父子进程特性== 为什么有父子进程? 僵尸进程(defunct进程) 什么是僵尸进程? 僵尸进程的底层原因 僵尸进程的危害与解决方法 孤儿进程 什么是孤儿进程? ...

  2. Linux进程:父子进程

    文章目录 一.什么是程序还有进程,之间的区别? 二.如何查看系统的进程? 三.什么是进程标识符 四.fork之后父子进程之间的变化 提示:以下是本篇文章正文内容,下面案例可供参考 一.什么是程序还有进 ...

  3. 利用管道实现父子进程读写数据

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h ...

  4. 小何讲进程: Linux进程控制编程 (fork、vfork)

    所谓进程控制,就是系统使用一些具有特定功能的程序段来创建进程.撤消进程以及完成进程在各种状态之间的转换, 从而达到多进程高效率并发执行和协调资源共享的目的.进程控制是进程管理和处理机管理的一个重要任务 ...

  5. Linux中父子进程、兄弟子进程之间通信方式--匿名管道pipe(适用于有血缘关系的进程)

    文章目录 编程环境: 进程间通信 IPC: 匿名管道(pipe): 父子进程间通信: 兄弟子进程间通信: 管道的读写行为: 读操作: 写操作: 查看管道缓冲区大小: 设置管道的非阻塞属性: 下载地址: ...

  6. linux c之通过管道父子进程实现同步通信

    1.父进程向子进程写数据 进程的概念和父进程向子进程写数据,我们之前有一片博客介绍过  http://blog.csdn.net/u011068702/article/details/54914774 ...

  7. apply_async进程不执行_[粉丝问答6]子进程进程的父进程关系

    一.粉丝提问 fork出的进程的父进程是从哪来的? 粉丝提问,一口君必须满足 二.解答 这个问题看上去很简单,但是要想把进程的父进程相关的所有知识点搞清楚,还是有点难度的,下面我们稍微拓展下,分几点来 ...

  8. 问题:子进程父进程哪个先执行:【转】关于 fork 和父子进程的理解

    2019独角兽企业重金招聘Python工程师标准>>> 关于 fork 和父子进程的理解   (http://blog.163.com/kingore@126/blog/static ...

  9. 【Linux】写实拷贝、父子进程间数据共享以及僵死进程

    目录 一.写实拷贝 二.父子进程间数据共享 三.僵死进程 我们都知道fork之后,会产生子进程,那么今天就来看一下,产生的子进程与父进程之间的数据共享问题.要说这个我们必须明确写实拷贝的概念 一.写实 ...

最新文章

  1. Hadoop学习笔记—7.计数器与自定义计数器
  2. 2014-3-6 星期四 [第一天执行分析]
  3. 可视化调试工具gdb-dashboard
  4. 放大倍数超5万倍的Memcached DDoS反射攻击,怎么破?
  5. 线性规划总结3——单纯形法和对偶单纯形法
  6. 二、OC的构造方法和descriprtion方法
  7. 商业计划书最好就是十页篇幅
  8. mkdir 函数_PHP mkdir()函数与示例
  9. SpringCloud 教程 | 第一篇: 服务的注册与发现Eureka
  10. java .jar怎么打开_jar文件怎么打开,小编教你如何打开jar文件
  11. R语言 MCMC算法及其实现
  12. iOS UDP和TCP测试工具sokit
  13. 何园–中国晚清第一园
  14. Unity-CharacterController(角色控制器)
  15. JDK19都出来了~是时候梳理清楚JDK的各个版本的特性了【JDK15特性讲解】
  16. list和set集合的遍历
  17. 逆战小白提升日記——网红时钟罗盘北京时间页代码
  18. 数据库基础知识(必读)
  19. 分子量 Molar Mass
  20. Javascript 面向对象编程(一):封装 ——转自阮一峰博客

热门文章

  1. 【大数据系列】hadoop单节点安装官方文档翻译
  2. iOS逆向工程(简单利用dumpdecrypted给ipa砸壳)
  3. JAVA如何才能导出这样的EXCEL?
  4. 工作两个月的感受随笔
  5. 正确使用PresentModalViewController
  6. 企业应该如何选型ERP?
  7. 学成在线--7.CMS页面管理开发(异常处理)
  8. 学成在线--2.CMS前端页面查询开发
  9. git 命令详解和常见问题解决
  10. 执行git命令时出现fatal: ‘origin‘ does not appear to be a git repository错误