进程之父子进程的关系

转载: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);  
    }  
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463324.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言快速排序算法

void sort(int *a, int left, int right) {if(left > right)/*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/{return ;}int i left;int j right;int key a[left];while(i < j) /*控制在当组内寻找一遍*/{while(i &l…

unbuntu使用经典界面

为什么80%的码农都做不了架构师&#xff1f;>>> 昨天升级到UBUNTU 11.04, 发现新的Unity界面很不适应&#xff0c;于是将其恢复到旧式经典界面&#xff0c;具体操作模式方法如下&#xff1a; 在已经登录的状态下&#xff0c;选择 [注销]然后在重新登录的时候&#…

学习:深入浅出之正则表达式(转)

本文是Jan Goyvaerts为RegexBuddy写的教程的译文&#xff0c;版权归原作者所有&#xff0c;欢迎转载。但是为了尊重原作者和译者的劳动&#xff0c;请注明出处&#xff01;谢谢&#xff01; 1. 什么是正则表达式 基本说来&#xff0c;正则表达式是一种用来描述一定数量文本…

C语言判断计算机存储是大端还是小端

计算机的一个int型数据是用多个字节表示的&#xff0c;如果在内存中存放时标称该数据的地址中存放的是数据的最低字节&#xff0c;就叫小端机&#xff0c;反之把高字节存放在标称地址中的则称为大端机。所以可以定义一个int变量&#xff0c;将其地址强制为char *型地址&#xf…

服务器开发中网络数据分析与故障排查经验漫谈

转载大牛的文章&#xff1a; https://mp.weixin.qq.com/s/6ZmiKUz4ZQvwLXkzzBrFcg

每天干的啥?(2019.3)

【本年目标】 【本月目标】【本月总结】 【3月每日记录】 去洗照片24张9寸&#xff0c;研究手机root&#xff08;y66不支持啊&#xff09;&#xff0c;下午党学习照相、看完第4课blake《用户数据ugame》、研究轮滑gif、晚上钢琴首次调律。 去妈妈那吃饭&#xff0c;学钢琴、佰洲…

【Andorid X 项目笔记】禁用ListView的Fling功能(1)

前言新的项目正在紧张开发中&#xff0c;初步估计2个月时间开发完成第一版&#xff0c;我负责Android端开发&#xff0c;由于不便过早公布&#xff0c;本系列将命名为“X项目笔记”&#xff0c;并于项目结束后最终公布名称。本系列主要记录与分享"X项目"中遇到的问题…

C语言题目地图上有m个城市,序号依次为1,2,3....m,刚开始你在1,若每次只能从当前城市去往当前序号加1或者加3的城市,要到达m城市(m3),有多少种走法

地图上有m个城市&#xff0c;序号依次为1,2,3....m&#xff0c;刚开始你在1&#xff0c;若每次只能从当前城市去往当前序号加1或者加3的城市&#xff0c;要到达m城市&#xff08;m>3&#xff09;,有多少种走法 要想到达m&#xff0c;则前一个应该是m - 1或者m -3&#xff1b…

Java IO/NIO教程

Java IO教程 http://tutorials.jenkov.com/java-io/index.html Java NIO教程 英文版&#xff1a; http://tutorials.jenkov.com/java-nio/index.html 中文版: Java NIO概述Java NIO ChannelJava NIO BufferJava NIO Scatter / GatherJava NIO 通道之间的数据传输Java NIO Selec…

SQL Server 数据库管理常用的SQL和T-SQL语句

--按姓氏笔画排序:SELECT*FROM TableName ORDERBY CustomerName COLLATE Chinese_PRC_Stroke_ci_as--数据库加密:SELECT encrypt(原始密码)SELECT pwdencrypt(原始密码)SELECT pwdcompare(原始密码,加密后密码)1--相同&#xff1b;否则不相同 encrypt(原始密码)SELECT pwdencry…

什么是一致性Hash算法?

原文链接&#xff1a;https://blog.csdn.net/bntX2jSQfEHy7/article/details/7954936 最近有小伙伴跑过来问什么是Hash一致性算法&#xff0c;说面试的时候被问到了&#xff0c;因为不了解&#xff0c;所以就没有回答上&#xff0c;问我有没有相应的学习资料推荐&#xff0c;当…

ZEN CART 在LINUX系统下设置邮箱方法---用GMAIL设置,方法选择SMTPAUTH

电子邮件发送方式smtpauth 电子邮件换行LF 使用HTML格式发送电子邮件true 发送电子邮件true电子邮件存档false 电子邮件出错信息false 用于显示的店主邮件地址salemulberrydiscountstore.com发件人邮件地址salemulberrydiscountstore.com 电子邮件必须从现有域名发送No 管理员电…

c++入门基础知识

命名空间刚开始接触c&#xff0c;我们会发现与C语言相比不光头文件有所不同&#xff0c;还会发现using namespce std&#xff1b;这句话&#xff0c;其实这就是c的命名空间。 (1) 概念命名空间是为了防止名字冲突提供更加可控的机制。命名空间分割了全局命名空间&#xff0c;其…

读书笔记之《得未曾有》

作者 安妮宝贝&#xff0c;2014年笔名改为“庆山” 感想 第一次读庆山的作品&#xff0c;可以书名来总结的一下&#xff0c;得未曾有——获得了一种未曾有过得感受。 一、感受作者 高晓松老师的节目里说过一句话&#xff0c;写作需要长时间的观察人性、需要极强的观察能力。庆山…

数据库索引的实现原理

转载&#xff1a;https://blog.csdn.net/kennyrose/article/details/7532032 强烈建议参阅链接&#xff1a;http://www.linezing.com/blog/?p798#nav-1 说白了&#xff0c;索引问题就是一个查找问题。。。 数据库索引&#xff0c;是数据库管理系统中一个排序的数据结构&…

斐波那契序列 集锦

[定理1] 标准Fibonacci序列&#xff08;即第0项为0&#xff0c;第1项为1的序列&#xff09;当N大于1时&#xff0c;一定有f(N)和f(N-1)互质 其实&#xff0c;结合“互质”的定义&#xff0c;和一个很经典的算法就可以轻松证明对&#xff0c;就是辗转相除法互质的定义就是最大公…

linux ssh密钥登录配置

首先确保服务器ssh服务已启动&#xff0c;用户能够正常登录&#xff0c;然后配置客户端&#xff0c;过程如下&#xff1a; 一、先用自已的用户登录到服务器&#xff0c;比如我用 uplinux 登录到服务器 二、运行 SSH Secure Shell 工具中的“Secure Shell Client ”&#xff0c;…

C++基础知识简答题

1、C 可执行程序的内存分布 BSS&#xff1a;Block Started by Symbol 存放程序中未初始化的全局变量 数据段&#xff1a; 存放已初始化的全局变量&#xff0c;静态内存分配 代码段&#xff1a; 存放执行代码 堆heap&#xff1a; 存放运行中动态分配的内存段&#xff0c;可扩张或…

linux驱动简单介绍

linux驱动简单介绍 驱动基本介绍 驱动。顾名思义就是“驱使硬件设备行动”。设备驱动与底层硬件之间打交道&#xff0c;按照硬件设备的具体操作方式来读写设备寄存器&#xff0c;最终完成一系列操作。 设备 驱动充当了应用程序和应用软件直接的纽带&#xff0c;它使得应用软件只…

远离客户陷阱小故事 转

出处&#xff1a; http://ilovecode.cnblogs.com 做项目做产品可以有3个境界&#xff1a;1 挣钱的&#xff0c;2 做品牌的&#xff0c;3 很酷的。有的人从境界1做到3&#xff0c;有得人从3做到1。 我是从1做到3&#xff0c;因为有了钱&#xff0c;你才能远离垃圾项目和不…