操作系统fork()进程

2023-11-04

1、fork()是创建进程函数。

2、c程序一开始,就会产生 一个进程,当这个进程执行到fork()的时候,会创建一个子进程。

3、此时父进程和子进程是共存的,它们俩会一起向下执行c程序的代码。

4、需要注意!!!子进程创建成功后,fork是返回两个值,一个代表父进程,一个代表子进程:代表父进程的值是一串数字,这串数字是子进程的ID(地址);一个代表子进程,值为0。

下面写一段代了解了解(注释很重要)
在这里插入图片描述
运行结果如下父进程printf出来的是子进程 的ID即那串数字,子进程printf的则为0:
在这里插入图片描述

深入学习

1-1.c

#include<unistd.h>
#include<stdio.h>
int main()
{
        int p1,p2;
        if(p1=fork())               /*子进程创建成功*/
                //父进程返回的是一串数字>1,满足条件,执行下面语句
           putchar('b');//首先输出b,之后该父进程自杀了(结束)
        else   //这里是由于子进程的fork为0,子进程在这里面执行
        {
                if(p2=fork())       //在这里子进程创建了自己的子进程(先凑合叫做孙进程吧),此时子进程fork返回孙进程的ID>1,则可以执行下面语句
                   putchar('c');//子进程执行,输出c
                else
                   putchar('a');           /*父进程执行*/
		//上面老师注释的父进程我认为是“孙进程”,而不是一开始的父进程,一开始的父进程putchar出b后,已经被杀死了,不信可以 printf("%d",p2);,看看是不是输出0,fork()为0,则为孙进程
        }
printf("\n");

}

执行结果(注意看代码注释,通俗点说就是父进程输出了b,子进程输出了c,孙进程输出a 。其实没有孙进程这种说法吧。)
在这里插入图片描述

1-2.c

#include<stdio.h> 
#include<sys/types.h>
#include<unistd.h> 
int main() 
{  
    int p1,p2;  
    while((p1=fork())==-1)//如果子进程创建失败则fork返回-1=-1,while循环不会跳出,直至创建成功,fork为子进程的ID或者0才可以跳出while循环
	printf("111");  //没有输出111.说明p1不等于-1,那说明子进程创建成功,直接跳出while循环
       // printf("%d\n",p1);     //父子进程都会执行这一句,谁先谁后是随机的,所以有可能先显示0再显示ID,否则反之
    if (p1==0)               //子进程的fork为0,满足此条件            
      putchar('b'); 	     //由子进程输出‘b’,接着子进程自杀
    else 		     //由于刚刚父进程不满足上面的if条件,所以来到else这下面执行
    {  
      while((p2=fork())==-1);  //重建子进程(第二个孩子)
      if (p2==0)             //第二个孩子满足fork=0  
       putchar('c'); 		//第二个孩子执行输出“c”
      else                   //父进程最终什么都不满足地来到这里
       {putchar('a');  	     //父进程输出“a”
	//printf("\n%d\n",p2);
	}
    } 
}//结果我猜正确的顺序是acb或者bac。这个要看父子进程的看快慢,就像赛跑。

执行结果
在这里插入图片描述

2-1.c

#include<stdio.h>
#include<unistd.h>
int main()
{
	int p1,p2,i;
	if(p1=fork())//此时父进程的fork为一串数字,子进程fork为0;父进程的fork>0,满足条件
 		for(i=0;i<5;i++)
		        printf("child %d\n",i);//说明创建进程成功,不管是男孩还是女孩
	else//子进程不满足上面if条件,从而来到这里
	{ 
 	if(p2=fork())//子进程来这里创建“孙”进程,此后子进程fork为一串数字即“孙”进程的ID;则孙进程的fork为0;子进程fork>0,满足条件
    		for(i=0;i<5;i++) 
			printf("son %d\n",i);
 	else//“孙”进程不满足上面if条件,从而来到这里
    		for(i=0;i<5;i++)  
			printf("daughter %d\n",i);//老师的理解和我的不一样吧。我认为这是子进程的子进程了,是个女儿。
	}
}

//输出结果的话,也是随机的

执行结果:
在这里插入图片描述
2-2.c

/*
author:Szymou
explain:
lockf(1,1,0)是锁上资源让该进程独自享用
lockf(1,0,0)是解锁资源,给其他进程用
下面的sleep用于该进程“休息一下”,休息的时候,其他进程可以用资源
这里的资源是个人认为是磁盘的缓冲区buffer
*/
#include<stdio.h>
#include<unistd.h>
int main()//每次printf的时候,系统会先将需要输出的字符存在缓冲区buffer里面
{
	int p1,p2,i;
	if(p1=fork())
	{
     	lockf(1,1,0);//锁上buffer自己享用
     	for(i=0;i<3;i++)  
		{
		printf("child %d\n",i);
		/*老师的默认第二个lockf(1,1,0)是一直锁上的,结果会是先全部输出son012,再输出其他,其他进程同理*/
     	lockf(1,0,0);//解锁给另外的子进程  
     	sleep(2);//其他子进程可以在父进程休眠的时候调用buffer使用
     	}
	}
	else
 	{
  		if(p2=fork())
			{ 
			    lockf(1,1,0);//锁上buffer自己享用
     			for(i=0;i<3;i++)  
     			{
     			printf("son %d\n",i);
    			lockf(1,0,0);
    			sleep(2);
    			}
  			}
		else
		{ 
		    lockf(1,1,0);//锁上buffer自己享用     //运行结果>>>>>
     		for(i=0;i<3;i++)                    //运行结果>>>>>
     		{
     		printf("daughter %d\n",i);
   	 	    lockf(1,0,0);
   	 	    sleep(2);
   	 	    }
		}
	 }return 0;
}

运行结果:
在这里插入图片描述
3-1.c

/*
author:Szymou
explain:
父进程称为a进程
往下就是b、c、d进程
*/
#include<stdio.h>
#include<unistd.h>
int main()
 {
    int p1,p2,p3,p4;
    while((p1=fork())==-1);//a进程在这里创建b进程

    if(p1!=0)//父进程称为a进程,进来了
    {
     	printf("process a(its id=%d,its father pid is %d)\n",getpid(),getppid());
    }
    else//b进程进来了
    {
        printf("precess b(its id=%d,its father pid is %d)\n",getpid(),getppid());
        while((p2=fork())==-1) ;//b进程创建c进程

        if(p2==0)//c进程进来
        {
            printf("precess c(its id=%d,its father pid is %d)\n",getpid(),getppid());
            while((p3=fork())==-1) ;//c进程创建d进程

            if(p3==0)//d进程进来
            printf("precess d(its id=%d,its father pid is %d)\n",getpid(),getppid());
       }
    }
return 0;
}

观察执行结果,会发现有些进程的父进程ID显示不是自己父进程的ID 这是因为其父进程死了,而她成了孤儿进程,被某进程收养了,所以显示的父进程ID是收养它的那个进程的ID,可以用命令ps
x查看当前进程,查找进程ID,即可明了。
在这里插入图片描述

应该怎么使得每个进程的父进程ID显示正确呢?
那就应该让该父进程别死,让它等待其子进程死后再死即可。这时候我们就应该使用一个函数了,这个函数是wait()。
作用是父进程执行到wait(),会被挂起来,等待其子进程结束后,自己才结束。

代码:

/*
author:Szymou
explain:
父进程称为a进程
往下就是b、c、d进程;
有一种情况:有些进程显示其父进程ID不是父进程ID,而是系统进程ID,这是因为父进程死后,子进程get不到父进程ID,从而成了孤儿,在乌班图下会被upstart收养,在CentOS下会被init收养。可以用ps x来查看;
wait()函数可以让当前父进程等待子进程结束,父进程才结束。这里引进这个函数,是因为,避免父进程死后,子进程没了爸爸,找不到爸爸的ID即getppid
*/

/*
    这两个头文件用于支持wait()函数
*/
#include <sys/types.h> 
#include <sys/wait.h>


#include<stdio.h>
#include<unistd.h>
int main()
 {
    int p1,p2,p3,p4;
    while((p1=fork())==-1);//a进程在这里创建b进程
    if(p1!=0)//父进程称为a进程,进来了
    {
     	printf("process a(its id=%d,its father pid is %d)\n",getpid(),getppid());
     	wait(NULL);
    }
    else//b进程进来了
    {
        printf("precess b(its id=%d,its father pid is %d)\n",getpid(),getppid());
        while((p2=fork())==-1) ;//b进程创建c进程
        if(p2!=0) wait(NULL);
	//sleep(1);
        else if(p2==0)//c进程进来
        {
            printf("precess c(its id=%d,its father pid is %d)\n",getpid(),getppid());
            while((p3=fork())==-1) ;//c进程创建d进程
            if(p3!=0) wait(NULL);
	    //sleep(1);
            else if(p3==0)//d进程进来
            printf("precess d(its id=%d,its father pid is %d)\n",getpid(),getppid());
       }
    }
return 0;
}

运行结果(不再会出现孤儿进程现象)
在这里插入图片描述

有什么问题可以在评论区一起讨论哦!一起学

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

操作系统fork()进程 的相关文章

随机推荐

  • 单细胞专题

    单细胞测序的概念 上节我们讲到转录组测序相关内容 这期将继续学习单细胞转录组测序 单细胞测序技术 single cell sequencing 简单来说 就是在单个细胞水平上 对基因组 转录组及表观基因组进行测序分析的技术 图1 图1 单细
  • 借助云开发搭建专属技术博客微信小程序(附源码)

    导语 一直对小程序开发很感兴趣 之前就准备做一款属于自己的小程序 无奈还需要购买云服务器和部署后台 有点麻烦 自从知道有了云开发这个免去服务器搭建和运维的一站式后端云服务 神器 就一鼓作气花了几个周末的时间做了一款自己的博客小程序 如果你也
  • ES写入性能的提升方案

    从社区上看到一个问题 回答了一下 总结了下提高写入性能的方案 服务端 1 refresh refresh interval 1s indices memory index buffer size 10 2 translog Index tr
  • vSphere使用技巧:自定义管理规范使用

    本文转载至 http blog chinaunix net uid 21089721 id 1565198 html 一 前言 我们在使用vCenter Client的时候 常常会使用模板来安装服务器 但是这样就会带来一些问题 例如WIND
  • Windows通过某端口号找对应的进程窗口句柄

    以下为 Qt通过netstat exe程序获取相关信息 通过端口号获取进程ID 的姊妹篇 通过端口号找对应的窗口句柄 以上所提及的API 均为Win32的系统API 不涉及Qt的相关方法
  • Shell Sort 希尔排序

    希尔排序 Shell Sort 又叫做缩小增量排序 diminishing increment sort 是一种很优秀的排序法 算法本身不难理解 也很容易实现 而且它的速度很快 插入排序 Insertion Sort 的一个重要的特点是 如
  • Oracle中没有 if exists(...)

    对于Oracle中没有 if exists 的语法 目前有许多种解决方法 这里先分析常用的三种 推荐使用最后一种 第一种是最常用的 判断count 的值是否为零 如下 declare v cnt number begin select co
  • 如何搭建自己的服务器机房

    1 地下室这种环境 铲成毛坯先做一遍防水防潮抗震套餐 这个便宜 相对 2 找国家电网拉两个不一样变电站的电线杆子来做380V 之前做过一个机房的这种需求 也就二百来万吧 3 每个运营商 不同机房 做两个方向两个井 两条8 16芯缆 运营商大
  • HTML5 详细介绍 及应用实例

    HTML5 概况 什么是 HTML5 HTML 5有两大特点 首先 强化了 Web 网页的表现性能 其次 追加了本地数据库等 Web 应用的功能 HTML 5是近十年来Web开发标准最巨大的飞跃 和以前的版本不同 HTML 5并非仅仅用来表
  • [MySQL]事务ACID详解

    专栏简介 MySql数据库从入门到进阶 题目来源 leetcode 牛客 剑指offer 创作目标 记录学习MySql学习历程 希望在提升自己的同时 帮助他人 与大家一起共同进步 互相成长 学历代表过去 能力代表现在 学习能力代表未来 目录
  • 版本管理工具——SVN

    SVN的下载和安装 1 1SVN服务器端的安装和配置 1 2SVN客户端的安装和配置 SVN的基本操作 SVN的常见问题 3 1解决文件提交冲突 一 SVN服务器端的安装和配置 1 VisualSVN下载 http www visualsv
  • 国内及Github优秀开发人员列表

    自从入了Android软件开发的行道 解决问题和学习过程中免不了会参考别人的思路 浏览博文和门户网站成了最大的入口 下面这些列表取名为 国内及Github优秀开发人员列表 就是浏览后的成果 虽然下述列表出自Android软件开发 文章定为不
  • python科研项目_通过科研人员论文项目等数据,训练识别导师/学生的分类器

    student and teacher classifier 通过科研人员论文项目等数据 训练识别导师 学生的分类器 代码包括特征选择基础 网格搜索确定特征选择方法参数 不平衡数据的处理 oversampling和undersampling
  • -day18面向对象进阶

    day18 面向对象进阶 课程目标 掌握面向对象进阶相关知识点 能更加自如的使用面向对象来进行编程 今日概要 成员 变量 实例变量 类变量 方法 绑定方法 类方法 静态方法 属性 成员修饰符 公有 私有 对象嵌套 特殊成员 对比 问题 洗衣
  • mysql group by 中文_MySQL GROUP BY 语句

    MySQL GROUP BY 语句 GROUP BY 语句根据一个或多个列对结果集进行分组 在分组的列上我们可以使用 COUNT SUM AVG 等函数 GROUP BY 语法 SELECT column name function col
  • 单片机学习 1-LED灯的点亮(全操作)

    LED灯 P0 P1 P2 P3结构图 除了P0端口需要自己外接上拉电阻 否则只能输入输出低电平 其它自带上拉电阻 因此都可以实现高低电平的输入输出 LED灯介绍 LED灯本质是发光二极管 单片机输入电流控制在3mA 20mA之间 可串联电
  • ubuntu pycharm 无法输入中文

    很多人反馈是和ubuntu20 04有关 但是其实应该是和pycharm20 2 3有关 只需要替换掉版本里面的jbr即可 1 下载jbr https confluence jetbrains com pages viewpage acti
  • 数组-第三大的数

    题意 给定一个非空数组 返回此数组中第三大的数 如果不存在 则返回数组中最大的数 要求算法时间复杂度必须是O n 示例 1 输入 3 2 1 输出 1 解释 第三大的数是 1 示例 2 输入 1 2 输出 2 解释 第三大的数不存在 所以返
  • 笔记本电脑运行特别慢怎么解决

    其实不管是笔记本电脑还是台式电脑 用久了肯定多多少少都会有点卡顿的情况出现 很多人的笔记本就是用久了就有这种情况 面对这种情况 如果大家想快速的解决问题 就一起学学今天的关于笔记本电脑运行特别慢怎么解决的内容吧 工具 原料 系统版本 win
  • 操作系统fork()进程

    1 fork 是创建进程函数 2 c程序一开始 就会产生 一个进程 当这个进程执行到fork 的时候 会创建一个子进程 3 此时父进程和子进程是共存的 它们俩会一起向下执行c程序的代码 4 需要注意 子进程创建成功后 fork是返回两个值