P10 Linux进程编程 fork创建子进程

目录

前言 

 01 fork()创建子进程

示例 1使用 fork()创建子进程。

02 fork创建新进程时发生了什么事?

 2.1 父、子进程中对应的文件描述符指向了相同的文件表 


前言 

                              

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨ 

🔥 推荐专栏2: 《C++_@ChenPi的博客-CSDN博客》✨✨✨

🛸推荐专栏3: ​​​​​​《链表_@ChenPi的博客-CSDN博客 》 ✨✨✨
🌺本篇简介  :  上一章我们讲了Linux进程的概念以及获取进程ID号和获取父进程的ID

                          这一章我们引进新的概念,父子进程

Linux 是一个多用户多任务的操作系统,每个用户可以同时运行多个程序

进程是程序运行的主体,包括进程的创建,调度和消亡的整个过程

当用户执行一个指令或者启动一个程序时,就创建了一个进程

一个运行的程序也可能有多个进程。

每个进程将被分配各种资源    

 01 fork()创建子进程

一个现有的进程可以调用 fork()函数创建一个新的进程,

调用 fork()函数的进程称为父进程,

由 fork()函 数创建出来的进程被称为子进程(child process),

fork()函数原型如下所示(fork()为系统调用):

2.1 fork()函数原型:

#include <unistd.h> pid_t fork(void); 

返回值: 

  1. 失败返回-1 不创建子进程,并设置 errno 
  2. 父进程的返回值pid为子进程的pid号,子进程的返回值为0

在诸多的应用中,创建多个进程是任务分解时行之有效的方法

  1. 譬如,某一网络服务器进程可在监听客 户端请求的同时,为处理每一个请求事件而创建一个新的子进程,与此同时,服务器进程会继续监听更多的 客户端连接请求
  2. 在一个大型的应用程序任务中,创建子进程通常会简化应用程序的设计,同时提高了系统 的并发性(即同时能够处理更多的任务或请求多个进程在宏观上实现同时运行)。

理解 fork()系统调用的关键在于,完成对其调用后将存在两个进程,

一个是原进程(父进程)、另一个 则是创建出来的子进程,

并且每个进程都会从 fork()函数的返回处继续执行,会导致调用 fork()返回两次值,

子进程返回一个值、父进程返回一个值,所以fork返回值后面的代码块也会调用两次

在程序代码中,可通过返回值来区分是子进程还是父进程。

fork()调用成功后,将会在父进程中返回子进程的 PID,而在子进程中返回值是 0;

如果调用失败,父进 程返回值-1,不创建子进程,并设置 errno。

fork()调用成功后,子进程和父进程会继续执行 fork()调用之后的指令,子进程、父进程各自在自己的进程空间中运行。

事实上,子进程是父进程的一个副本

  1. 譬如子进程拷贝了父进程的数据段、堆、栈以及继承 了父进程打开的文件描述符
  2. 父进程与子进程并不共享这些存储空间
  3. 这是子进程对父进程相应部分存储 空间的完全复制
  4. 执行 fork()之后,每个进程均可修改各自的栈数据以及堆段中的变量,而并不影响另一个进程

示例 1使用 fork()创建子进程。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>int main()
{int pid =  fork(); //父进程的返回值pid为子进程的pid号,子进程的返回值为0switch (pid){case -1:printf("fork error\n");break;case 0:printf("this is child ;PID = %d\n",getpid());break;default:printf("this is father;PID = %d\n",getpid());break;}return 0;
}

 

 从打印结果可知,fork()之后的语句被执行了两次,所以 switch…case 语句被执行了两次

  1. 第一次进入 到了"case 0"分支,表示进入子进程
  2. 第二次进入到了 default 分支,表示当前处于父进程
  3. 父进程的返回值pid为子进程的id号,子进程的返回值为0 

02 fork创建新进程时发生了什么事?

调用 fork()函数之后,子进程会获得父进程所有文件描述符的副本

这些副本的创建方式类似于 dup(), 这也意味着父、子进程对应的文件描述符均指向相同的文件表,如下图所示:

由此可知

子进程拷贝了父进程的文件描述符表,使得父、子进程中对应的文件描述符指向了相同的文件表

也意味着父、子进程中对应的文件描述符指向了磁盘中相同的文件,

因而这些文件在父、子进程间实 现了共享,

譬如,如果子进程更新了文件偏移量,那么这个改变也会影响到父进程中相应文件描述符的位置 偏移量。  

 2.1 父、子进程中对应的文件描述符指向了相同的文件表 

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define MY_FILE "./file.txt"int main()
{char buf [128];int fd = open(MY_FILE,O_RDWR|O_CREAT,0600);if(-1 == fd){perror("open error? :");exit(-1);}int pid = fork();switch (pid){case -1:printf("fork error\n");break;case 0:for(int i = 0;i<4;i++)write(fd," child",strlen(" child"));close(fd);break;default:for(int i = 0;i<4;i++)write(fd," father",strlen(" father"));close(fd);break;}return 0;
}

上述代码中,父进程 open 打开文件之后,才调用 fork()创建了子进程,

所以子进程了继承了父进程打 开的文件描述符 fd,我们需要验证的便是两个进程对文件的写入操作是分别各自写入、还是每次都在文件 末尾接续写入

有上述测试结果可知,此种情况下

父、子进程分别对同一个文件进行写入操作,结果是接续写

不管是父进程,还是子进程,在每次写入时都是从文件的末尾写入很像使用了 O_APPEND 标志的效果。

其原 因也非常简单

子进程继承了父进程的文件描述符,两个文件描述符都指向了一个相同的文件表,意味着它们的文件偏移量是同一个、绑定在了一起,相互影响,子进程改变了文件的位置 偏移量就会作用到父进程,同理,父进程改变了文件的位置偏移量就会作用到子进程

但是执行结果不一定是父进程先执行或者子进程先执行,这个不一定的,这个要看系统的调度了 
 

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

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

相关文章

异步回调模式

异步回调 所谓异步回调&#xff0c;本质上就是多线程中线程的通信&#xff0c;如今很多业务系统中&#xff0c;某个业务或者功能调用多个外部接口&#xff0c;通常这种调用就是异步的调用。如何得到这些异步调用的结果自然也就很重要了。 Callable、Future、FutureTask publi…

半导体划片机助力氧化铝陶瓷片切割:科技与工艺的完美结合

在当今半导体制造领域&#xff0c;氧化铝陶瓷片作为一种高性能、高可靠性的材料&#xff0c;被广泛应用于各种电子设备中。而半导体划片机的出现&#xff0c;则为氧化铝陶瓷片的切割提供了新的解决方案&#xff0c;实现了科技与工艺的完美结合。 氧化铝陶瓷片是一种以氧化铝为基…

《巫师3》缺失vcomp110.dll如何解决,如何快速修复vcomp110.dll丢失问题

在日常使用电脑的过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“vcomp110.dll丢失”。这个错误提示通常意味着vcomp110.dll文件在系统中无法找到或加载。那么&#xff0c;vcomp110.dll丢失的原因是什么&#xff1f;它对电脑有什么影响&#xff1f;本…

高德地图vue实现自定义标点热力图效果(缩放时展示不同数据)

高德地图插件引入省略。。。样式和vue基础组件省略。。。 如果每个标点没有数值&#xff0c;则可以用点聚合来实现功能下面例子&#xff0c;每个标点会有按市统计的数值&#xff0c;而且缩放一定程度时&#xff0c;需要展示按省统计的标点&#xff0c;因此需要自定义标点样式和…

leetcode刷题日志-54螺旋矩阵

思路&#xff1a; 上下左右设置四个边界 每走完一行或者一列&#xff0c;移动相应边界&#xff0c;当左边界大于右边界&#xff0c;或者上边界大于下边界时&#xff0c;结束 代码如下&#xff1a; class Solution {public List<Integer> spiralOrder(int[][] matrix) {…

线程上下文切换

线程上下文切换 巧妙地利用了时间片轮转的方式, CPU 给每个任务都服务一定的时间&#xff0c;然后把当前任务的状态保存下来&#xff0c;在加载下一任务的状态后&#xff0c;继续服务下一任务&#xff0c;任务的状态保存及再加载, 这段过程就叫做上下文切换。时间片轮转的方式…

冒泡排序和直接选择排序(C/C++实现)

文章目录 冒泡排序(交换排序&#xff09;基本思想特性总结代码实现 直接选择排序基本思想特性总结代码实现&#xff08;优化&#xff0c;每次循环同时选择最小和最大的数&#xff09; 冒泡排序(交换排序&#xff09; 基本思想 基本思想&#xff1a;所谓交换&#xff0c;就是根…

class065 A星、Floyd、Bellman-Ford与SPFA【算法】

class065 A星、Floyd、Bellman-Ford与SPFA【算法】 2023-12-9 19:27:02 算法讲解065【必备】A星、Floyd、Bellman-Ford与SPFA code1 A*算法模版 // A*算法模版&#xff08;对数器验证&#xff09; package class065;import java.util.PriorityQueue;// A*算法模版&#xff…

两年外包生涯做完,感觉自己废了一半。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入南京某软件公司&#xff0c;干了接近2年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…

laravel的ORM 对象关系映射

Laravel 中的 ORM&#xff08;Eloquent ORM&#xff09;是 Laravel 框架内置的一种对象关系映射系统&#xff0c;用于在 PHP 应用中与数据库进行交互。Eloquent 提供了一种优雅而直观的语法&#xff0c;使得开发者可以使用面向对象的方式进行数据库查询和操作。 定义模型&…

结合ColorUI组件开发微信小程序

1.自定义组件生命周期函数&#xff1a; Component({data: {},attached() {console.log("自定义组件生命周期函数 attached--先执行");this.getPos();},ready() {console.log("ready生命周期函数---在attached之后执行")},methods: {getPos() {var that th…

数据结构:位图、布隆过滤器以及海量数据面试题

位图、布隆过滤器以及海量数据面试题 1.位图1.1概念1.2实现1.3位图应用 2.布隆过滤器2.1布隆过滤器的提出2.2布隆过滤器的概念2.3布隆过滤器的查找2.4布隆过滤器的实现2.5布隆过滤器的删除2.6布隆过滤器的优点2.7布隆过滤器的缺点 3.海量数据面试题3.1哈希切分3.2位图应用3.3布…

如何成为前1%的程序员

如果你想成为前1%的程序员&#xff0c;你必须遵循1%的程序员做什么&#xff0c;了解其他99%的人不做什么。在现代&#xff0c;我们有各种学习平台&#xff0c;里面充满了与编程相关的视频、图文以及其他资料。 举例来说&#xff0c;我作为编程的初学者&#xff0c;去寻找路线图…

IDEA2023找不到add framework support怎么解决

问题: 我的idea版本是2023.01&#xff0c;新版idea右键项目没有Add Framework Support&#xff0c;help里面也找不到相关的。 从project structue的facets里面添加就行了&#xff0c;都是一样的。 1.依旧是新建一个项目 2.file-->project structure--->facets 左上角加…

Android studio如何安装ai辅助工具

引言 在没有翻墙的情况下&#xff0c;即单纯在公司打工&#xff0c;经测试&#xff0c;大部分ai工具都是使用不了的&#xff08;比如各种gpt,codeium,copilot&#xff09;&#xff0c;根本登录不了账号&#xff0c;但有一个国内的codegeex是可以使用的&#xff0c;在这里不对各…

Android app性能优化指南

Android应用性能优化指南 提高应用程序的性能以实现更流畅的用户体验和更高的可见度。 性能在任何应用程序的成功中发挥着重要的作用。为用户提供流畅无缝的体验应该是开发人员的重点。 应用程序大小 在用户开始使用我们的应用程序之前&#xff0c;他们需要下载应用程序并将…

DTCC2023大会-DBdoctor-基于eBPF观测数据库-附所有PPT下载链接

DTCC2023大会-DBdoctor-基于eBPF观测数据库-附所有PPT下载链接 8月16日—18日,第14届中国数据库技术大会(DTCC-2023)在北京国际会议中心举行。聚好看在大会上首次发布基于eBPF观测数据库性能的产品DBdoctor&#xff0c;受到了业界广泛的关注。近期几位业内同仁过来要大会的PPT…

2024考研数学二备考历程

GoodNotesGoodNotes apphttps://share.goodnotes.com/s/bhsraJMZ6OJwuYJb3OWnzP

C/C++之输入输出

文章目录 一.C语言的输入输出1.printfi. 输出整数ii. 浮点数iii.字符 & 字符串 2.scanfi.整数ii.浮点数iii. 字符 & 字符串 3.特殊用法i. * 的应用ii. %n 的应用iii. %[] 的应用 二.C中的输入输出1.couti. 缓冲区&#xff08;buffer&#xff09;ii. cout之格式化输出 2…

Proteus仿真--串口发送数据到2片8×8点阵屏滚动显示

本文介绍2片88点阵屏滚动显示设计&#xff08;完整仿真源文件及代码见文末链接&#xff09; 仿真图如下 仿真运行视频 Proteus仿真--1602LCD显示电话拨号键盘按键实验&#xff08;仿真文件程序&#xff09; 附完整Proteus仿真资料代码资料 链接&#xff1a;https://pan.baidu…