《Linux从练气到飞升》No.17 进程创建

news2025/1/21 11:57:17

  

🕺作者: 主页

我的专栏
C语言从0到1
探秘C++
数据结构从0到1
探秘Linux
菜鸟刷题集

😘欢迎关注:👍点赞🙌收藏✍️留言

🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢阅读!!!

目录

前言

fork函数

fork函数返回值

写时拷贝

fork常规用法

fork调用失败的原因

fork面试题

后记


前言

之前我们在进程基本概念中讲述过fork可以创建子进程(请在《探秘Linux》专栏中查看),但是我们只是大概讲述了一下它的功能和大致原理,算作是初识,本篇将更为详细的讲述它的用法——创建进程

fork函数

在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。

在我们想要使用fork函数时,注意一下几点:

#include <unistd.h>//记得包头文件

pid_t fork(void);//fork函数的返回值是pid_t,注意转化()

返回值:子进程中返回0,父进程返回子进程id,出错返回-1

 进程调用fork函数以后,内核做了什么?

  • 分配新的内存块和内核数据结构给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表当中
  • fork返回,开始调度器调度

如下图:

 当一个进程调用fork之后,就有两个二进制代码相同的进程。而且它们都运行到相同的地方。但每个进程都将可以开始它们自己的旅程,我们来测试一下~

#include <stdio.h>
#include <unistd.h>

int main( void )
{
    pid_t pid;
    printf("Before: pid is %d\n", getpid());
    if ( (pid=fork()) == -1 )perror("fork()"),exit(1);
    printf("After:pid is %d, fork return %d\n", getpid(), pid);
    sleep(1);
    return 0; 
}

 运行结果:

 这里看到了三行输出,

一行before,两行after。

进程4863先打印before消息,然后它有打印after。

另一个after消息有4864打印的。

注意到进程4864没有打印before,

为什么呢?如下图所示

 

 所以,fork之前父进程独立执行,fork之后,父子两个执行流分别执行。注意,fork之后,谁先执行完全由调度器决定。

fork函数返回值

  • 子进程返回0
  • 父进程返回的是子进程的pid

写时拷贝

通常,父子代码共享,父子再不写入时,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。具体见下图:

fork常规用法

  • 一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如,父进程等待客户端请求,生成子进程来处理请求。
  • 一个进程要执行一个不同的程序。例如子进程从fork返回后,调用exec函数

fork调用失败的原因

  • 系统中有太多的进程,进程太多,可能就没有多余的内存来创建进程了,进而导致fork调用失败。
  • 实际用户的进程数超过了限制

fork面试题

请你描述一下folk创建子进程,操作系统都做了什么?

我们推一下,fork创建子进程,也就是说系统里多了一个进程。进程等于内核数据结构加进程代码和数据,而进程代码和数据一般从磁盘中来。也就是你的c或c++程序加载之后的结果。那么我们再倒退回去,folk创建子进程,操作系统就会从磁盘中加载c或c++程序加载之后的结果,然后同时创建内核数据结构,包括地址空间、页表等,进而形成一个新的进程。

fork之后子进程是否能够使用父进程的全部代码?

创建子进程,给子进程分配对应的内核结构。必须子进程自己独有了,这是因为进程具有独立性,理论上子进程要有自己的代码和数据。可是一般而言我们没有加载的过程,也就是说子进程没有自己的代码和数据,所以子进程只能使用父进程的代码数据。但是代码都是不可被写的,只能读取,所以父子共享没有问题,但是数据可能被修改的,所以必须分离。

但是我们还没有说到一个问题:子进程代码共享是否是所有的?还是只是说fork之后的?

实际上我们的代码汇编之后会有很多行代码,而且每行代码加载到内存之后都有对应的地址,因为进程随时可能被中断,可能并没有执行完就中断了,下次回来还必须从之前的位置继续运行。就要要求 CPU必须随时记录下当前进程执行的位置,所以CPU内有对应的寄存器,数据用来记录当前进程的执行位置。我们之前讲过,寄存器在CPU内只有一份,寄存器的数据是可有多份的,这个寄存器数据也就是进程的上下文。那么这个进程的上下文数据要不要给子进程呢?答案是要的,虽然复制进程各自调的,各自会修改EIP(程序计数器),但是已经不重要了,因为子进程已经认为自己的EIP其实值就是fork之后的代码,它必须共享所有的代码。

操作系统为何要选择写时拷贝技术对父子进程进行分离?

总结起来是两点:

一、用的时候再给你分配,是高效使用内存的一种表现。

二、操作系统无法在代码执行前预知哪些空间会被访问?

展开谈谈:

试想一下,对于数据而言,创建进程的时候,就直接拷贝分离。是不是会浪费内存?可能拷贝子进程根本就不会用到的数据空间,即便是用到了,也可能只是读取,而我们创建子进程,不需要将不会被访问的或者只会读取的数据拷贝一份。

但是,什么数据值得拷贝呢?将来会被父或子进程写入的数据。但是一般而言,即便是操作系统,也无法提前知道哪些空间可能会被泄露,而且就算提前拷贝了,也不一定会立马使用。所以操作系统选择了写时拷贝技术来进行将父子进程的数据进行分离。写时拷贝是一种延迟申请技术,它可以提高整机内存的使用率的同时也完成了进程独立性的技术保证。

后记

本篇我们较为详细的讲述了fork函数的使用,以及它的相关原理,请结合进程概念那篇博客一起食用~

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

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

相关文章

EdifierW200btfree耳机说明书

Edifier W200bt free 耳机说明书。

【MySQL系列】Select语句单表查询详解(二)ORDERBY排序

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

static关键字(实例成员方法可以访问静态变量,但是静态成员方法不能直接访问非静态变量或者非静态方法)

1、静态static关键字概述 static是静态的意思&#xff0c;可以修饰成员变量和成员方法。static修饰成员变量表示该成员变量只在内存中只存储一份&#xff0c;可以被共享访问、修改。静态成员变量&#xff08;有static修饰&#xff0c;属于类&#xff0c;内存中加载一次&#xf…

vue3中引入百度地图

话不多说直接开干 1.第一种方式 百度地图地址 打开 https://lbsyun.baidu.com/index.php?title%E9%A6%96%E9%A1%B5 然后点进去地图 然后再这个功能里面选择一个地图&#xff0c;然后跳转页面 然后一直下滑 滑到底部 点击这个 跳转到这个页面 然后点击进入demo这个 然后到这个…

什么是Flex布局?请列举一些Flex布局的常用属性。

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ Flex布局&#xff08;Flexible Box Layout&#xff09;⭐ Flex布局的常用属性⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之…

Windows用户如何安装Cpolar

目录 概述 什么是cpolar&#xff1f; cpolar可以用在哪些场景&#xff1f; 1. 注册cpolar帐号 1.1 访问官网站点 2. 下载Windows版本cpolar客户端 2.1 下载并安装 2.2 安装完验证 3. token认证 3.1 将token值保存到默认的配置文件中 3.2 创建一个随机url隧道&#x…

Spring Boot(Vue3+ElementPlus+Axios+MyBatisPlus+Spring Boot 前后端分离)【二】

文章目录 Spring Boot(Vue3ElementPlusAxiosMyBatisPlusSpring Boot 前后端分离)【二】项目介绍项目功能/界面项目操作界面 技术栈 实现功能02-创建项目基础界面需求分析/图解思路分析代码实现 Spring Boot(Vue3ElementPlusAxiosMyBatisPlusSpring Boot 前后端分离)【二】 项目…

c语言函数指针和指针函数的区别,以及回调函数的使用。

函数指针是什么&#xff0c;函数指针本质也是指针&#xff0c;不过是指向函数的指针&#xff0c;存储的是函数的地址。 指针函数是什么,指针函数其实就是返回值是指针的函数&#xff0c;本质是函数。 函数指针是如何定义的呢&#xff0c;如下 void (*pfun)(int a,int b) 这…

Could not resolve all artifacts for configuration ‘:classpath‘.

不与世俗为伍。哪怕这是自己许给自己的诅咒。 —— 宫崎骏 《红猪》 出现的问题 Caused by: org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$ArtifactResolveException: Could not resolve all artifacts for configuration ‘:classpath’. 解…

Qt 自定义菜单、右键菜单

在接触Qt这段时间以来&#xff0c;经常遇到菜单项的问题&#xff08;右键菜单、托盘菜单、按钮菜单等&#xff09;&#xff0c;QMenu用于菜单栏,上下文菜单,弹出菜单等&#xff0c;利用QMenuQAction就可以达到效果&#xff01; 右键菜单实现&#xff1a;通过重写contextMenuEv…

Three.js + Theatre.js WebGL动画制作简明教程

在这个教程中&#xff0c;我们将介绍 Theatre.js 的基础知识并探索如何制作令人惊叹的动画序列。 我们将演示如何为 Three.js 立方体制作动画、集成引人注目的视觉效果、修改颜色、试验 HTML 元素以及以特定时间间隔将动画与声音播放同步。 推荐&#xff1a;用 NSDT编辑器 快速…

CSS选择器讲解!!!

CSS选择器 一. 常用的CSS基本选择器1.标签(元素)选择器2.类选择器3.id选择器4.类选择器和标签选择器的区别5.通配符选择器 二.复合选择器(2种)1.交集选择器2.并集(群组)选择器 三.属性选择器四.关系选择器1.后代选择器2.子代选择器3.相邻兄弟选择器4.通用兄弟选择器 五.伪元素选…

SpringMVC探秘: 实现MVC模式的Web应用

文章目录 1. SpringMVC概述1.1. 什么是SpringMVC&#xff1f;1.1.1. MVC与SpringMVC 1.2. SpringMVC项目的优势 2. SpringMVC项目的创建与使用2.1. 创建SpringMVC项目2.2. 设置路由2.3. 获取参数2.3.1. 获取一个参数2.3.2. 获取多个参数2.3.3. 获取日期参数2.3.4. 参数重命名Re…

C++之fileno用法实例(一百八十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

智慧煤矿:煤矿井下视频监控汇聚/AI智能分析监管预警系统解决方案

一、背景分析 随着科技的不断进步&#xff0c;视频监控技术在各个领域得到了广泛应用&#xff0c;其中包括煤矿行业。智慧煤矿方案通过引入视频监控系统&#xff0c;可以实现对煤矿生产过程的实时监控和管理&#xff0c;提高矿山安全性和生产效率。为解决井下作业距离地面远&a…

Spring之Spring案例分析

Spring案例分析 Spring案例分析 摘要引言词汇解释详细介绍不同领域的案例分析实战项目示例注意事项总结 参考资料 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&#x1f466;&#x1f3fb; 《java 面试题大全》 &#x1f369;惟余辈才疏学浅&#xff0c;临摹之…

APP Store上线问题及解决方案

将iOS应用上线到App Store可能会涉及一些问题&#xff0c;在上线iOS应用之前&#xff0c;确保你充分测试应用&#xff0c;遵循苹果的开发者指南和审核规则&#xff0c;以及关注用户的反馈&#xff0c;这些都能帮助你尽可能地解决问题并提供优秀的用户体验。以下是一些可能的问题…

juc基础(三)

目录 一、读写锁 1、读写锁介绍 2、ReentrantReadWriteLock 3、例子 4、小结 二、阻塞队列 1、BlockingQueue 简介 2、BlockingQueue 核心方法 3、案例 4、常见的 BlockingQueue &#xff08;1&#xff09;ArrayBlockingQueue(常用) &#xff08;2&#xff09;Li…

Prompt本质解密及Evaluation实战(二)

一、LangChain基于evaluation的prompt使用解析 我们来看下LangChain中关于prompt的使用&#xff0c;下面是取自LangChain源码中的一个经典的示例&#xff0c;描述了AI模型被授予访问几种工具来帮助回答用户的问题&#xff0c;其中“tool_descriptions”是至关重要的&#xff0…

React生命周期(新-旧)

文章目录 前言1、生命周期介绍2、钩子函数介绍 生命周期的三个阶段一、生命周期&#xff08;旧&#xff09;1.初始化阶段(挂载阶段)① constructor② componentWillMount③ render④ componentDidMount 2.更新阶段① shouldComponentUpdate② componentWillUpdate③ render④ c…