进程的创建之fork()函数

fork()函数创建进程举例 F0YXIuY3Nkbi5uZXQvNy83L0IvMV9yYWxmX2h4MTYzY29tLmpwZw =30x30) 居中的图片: 居中并且带尺寸的图片: 当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。 如何插入一段漂亮的代码片 去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片. // An highlighted block var foo = 'bar... 阅读详情
一、引子:

就像世上万物都有产生、发展、消亡的过程,每个进程都有被创建、执行一些程序以及最后消亡的过程,在Linux系统中,第一个进程是系统固有的、与生俱来的或者说是由内核的设计者安排好的,内核在引导并完成了基本的初始化以后,就有了系统的第一进程。并且所有的进程都是由这个原始进程或者它的子孙后代所创建,都是这个进程的“后代”。

在Linux系统中,一个新的进程一定要由一个已经存在的进程复制出来,而不是创建出来(而所谓的创建就是复制)而这里说的创建其实就是把原来的进程分配的资源、包括属于最低限度的task_struct数据结构和系统空间栈、堆进行共享;还要设置这个进程的系统空间栈,使的这个进程很像新的进程,其实你们都被骗了,以为这个进程是刚刚创建好的,其实这个进程更像是一个“克隆体”。当这个进程被调度运行的时候,其返回地址,也就是下一条指令进行恢复运动。其实这个新的进程就像新生儿一样,但是它却可以独立行走,拥有自己的独立意识。


二、进程类概念详解:

父进程(Parent Process)指已创建一个或多个子进程的进程。

子进程:指的是由另一进程(对应称之为父进程)所创建的进程。

第一进程:所有进程的祖先叫做进程0,idle进程或者swapper进程,它是在Linux的初始化阶段从无到有的创建的内核进程(该进程描述符使用的是静态分配的数据结构,其他进程都是动态分配的。进程0调用start_kernel()函数初始化内核需要的所有数据结构,激活中断,创建一个进程1 的内核进程(init进程)

孤儿进程: 当父进程结束以后, 子进程未结束, 子进程的父进程变为 init 。 

僵死进程(僵尸进程): 父进程未结束, 而子进程结束, 父进程未获取子进程的退出数据, 这时, 子进程成为僵死进程。  

进程1:init进程,init 这个进程是守护进程。 init 类型与孤儿院, 负责处理这些孤儿进程退出以后的一些状态 。


三、Linux进程的创建趣味分析:

由上述所说,进程是由复制而来,那么到底是怎么复制的呢,具体是怎么实现的呢,以及又有什么坑等着我们去填埋呢。首先讲解进程的创建就像是一个已经存在的“父进程”进行 生物上细胞分裂一样地复制出一个和自己一样的“子进程”,这里的一样指的是几乎一样,一些细节后序 将会做出补充,这里所谓的“细胞分裂”只是抽象化的进行解释一下,实际上复制出来的子进程有自己的task_struc结构和系统空间堆栈,与它的父进程共享父进程所拥有的资源。例如父进程打开了五个文件,那么子进程也有五个打开的文件,而且这些文件的当前读写指针也停在相同的地方。所以这些做的就是“复制”的操作。Linux提供了一个系统调用函数叫fork()函数,刚好用来作为进程的复制,那么它到底有什么特点呢,我们接着进行fork()函数的分析。


四、fork()函数

fork()函数定义:

fork()函数是Linux系统上用来创建进程的一个系统调用函数,它是一个有趣的函数,为什么这么说呢?因为若成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记(即子进程的pid(Linux中,每个进程有一个pid,类型pid_t,由getpid()取得)用法(pid_t fpid  =  fork()));否则,出错返回 -1。fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本一样。

为什么fork()函数会返回两次呢?

由于在复制时复制了父进程的堆栈段,所以两个进程都停留在fork()函数中,等待返回。因此fork()函数会返回两次,一次是在父进程中返回,另一次是在子进程中返回,这两次的返回值是不一样的。 fork()调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:

1.在父进程中,fork()函数返回新创建子进程的pid;

2.在子进程中,fork()函数返回0;

3.如果出现错误,则fork()函数返回一个负值。

理解:解释fork()函数返回的值为什么在父子进程中不同。"其实就相当于链表,进程形成了链表,父进程的fork()函数返回的值指向子进程的pid(进程id), 因为子进程没有子进程,所以其fork()函数返回的值为0(类似于与单链表的null)."

五、扩充:

1. getpid(); 用于获取调用 getpid 这个函数的进程的 pid;

2. getppid(); 用户获取调用 getppid 这个函数的进程的父进程 pid;

3. 调用 fork 函数的进程为新进程的父进程。即就是,通过 fork 创建的进程与原进程是父子关系。

4. fork 之后,父子进程之间的数据共享问题:

全局数据----------------------不共享
栈区数据----------------------不共享
堆区数据----------------------不共享


5.文件描述符问题:

子进程能不能使用 fork 之前 open 返回的文件描述符?

如图所示:

答案:父进程对于文件描述符共享,并且共享文件偏移量


【linuxC语言】进程概念与fork 在 Linux 系统编程中,进程是计算机中正在执行的程序的实例。每个进程都有自己独立的地址空间、代码段、数据段、堆栈等,使得它们能够彼此独立运行,互不干扰。Linux 系统中的进程是通过进程标识符(PID)来唯一标识的。而在 Linux 中,fork() 是一个非常重要的系统调用,用于创建新的进程。调用 fork() 后,将在原来的进程之上创建一个新的进程,新进程是原进程的一个副本,但具有自己独立的地址空间。本文将探讨进程的概念以及 fork() 函数的用法和作用。 阅读详情

相关推荐

偷懒必备:3种方法快速移植MFC界面资源(含.rc文件打不开解决方案)

本文针对MFC桌面应用开发,详细介绍了三种快速移植界面资源的实战方法:直接编辑.rc文件、利用Visual Studio“添加现有项”进行可视化挂载,以及双实例拖拽应急方案。文章重点剖析了.rc文件无法打开的常见问题,提供了通过修复rc.exe等关键文件来根治此问题的解决方案,帮助开发者高效复用资源,规避ID冲突等陷阱。

weixin_28358083的博客 273

Unix系统分叉函数fork()

最近一直在学习操作系统的知识,今天闲逛在BBS上看到一道题挺有意思: int main() { int x = 5; if(fork()) { x += 30; cout<<x<<endl; } else { cout<<x<<endl; } return 0; }问题是输出是什么? 于是查询fork()函数,可知: 头文件: #include

Leotyliu的专栏 947

科研党福音:如何用Zotero+Paper Agent打造你的AI论文速递系统(附详细配置教程)

本文为科研工作者提供了一套利用Zotero和开源工具Paper Agent构建自动化AI论文速递系统的详细教程。该系统能基于用户在Zotero中的文献库智能学习研究兴趣,每日自动从arXiv等平台筛选、下载并深度解读最相关的前沿论文,生成个性化日报,实现从被动接收到主动精准获取的知识工作流重塑。

kite3的博客 514

C语言中的fork

C语言中的函数,fork在英文中是分叉的意识,在C语言中,执行过fork的进程会分叉出一个新的进程。新进程被成为子进程,原来的进程被称为父进程。这里举两个例子说明一下fork的功能 分析 程序在执行到fork的时候克隆出了子进程,子进程具有当前进程的一切资源。子进程从fork开始执行,并不执行fork前面的代码。fork之后的代码有两个进程在执行,因此输出了两次。而且fork之后父子进程不共享数据,因此两边数据不互相影响,一开始i=0,i++之后i都等于1。同时由于父子进程不共享数据,因此父子进程要通信只

weixin_48885322的博客 9157

算法 A 求稳健平均值和稳健标准差

文章目录算法原理代码 算法原理 算法 A 来自 GB/T 6379.5。应用此算法计算得到数据平均值和标准差的稳健值。稳健性是估计算法的特点,而不是其产生的估计值的特点,因此严格来说,称由此算法计算的平均值和标准差是稳健的是不确切的。然而,为避免使用繁琐的术语,“稳健均值”和“稳健标准差”应理解为利用稳健算法计算的总体均值和总体标准差的均值估计。 设数据为 xi,i∈(1,2,⋯ ,n)x_i, i\in(1,2,\cdots,n)xi​,i∈(1,2,⋯,n),记稳健平均值为 x∗,s∗x^*, s^*x

zhuo木鸟的博客 9254

基于 Datawhale 开源量化投资学习指南(10):基于 LightGBM 的量化选股

通过本篇文章,我们深入探索了如何运用 LightGBM 机器学习模型实现量化选股。首先,我们通过获取股票的历史数据,进行特征工程和标签制作,将选股问题转化为一个分类问题。接着,我们使用 LightGBM 训练模型,并在验证集和测试集中评估了模型的表现。该选股策略的核心在于结合机器学习算法,从历史数据中寻找能够捕捉股票短期涨跌的关键特征,从而为投资者提供辅助决策支持。虽然本文的模型取得了一定的效果,但这只是量化投资领域的一小部分。

不想宅的冷同学 1346

linux下C语言fork(),操做系统概念Linux下用 C语言 fork()函数建立进程的实验及解释...

这是咱们操做系统课的一个实验linux1、实验目的:加深对进程概念的理解,明确进程和程序的区别。进一步认识并发执行的实质。认识进程生成的过程,学会使用fork生成子进程,并知道如何使子进程完成与父进程不一样的工做。2、实验要求:进行Linux(可选)下的建立进程实验并提供截图和源代码web3、实验准备首先学习了一下fork()的用法和特色,这几点是要注意的:并发一、进程能够看作程序的一次执行过程。...

weixin_36314050的博客 870

树莓派4B:控制步进电机

文章目录准备阶段接线阶段树莓派程序 准备阶段 准备以下物品,淘宝都可以买到: 57步进电机 电源开关(220v转24v,3A,72W) 步进电机驱动器 电源线 电线 杜邦线 树莓派4B一套 具体型号如下: 接线阶段 整体:接线效果如下图 电源开关起220v转24v作用,很好接线,输出24v接入步进电机驱动器 步进电机驱动器的 A+ A- B+ B- 按提示接步进电机四线,步进电机上就会有说...

学习路上的鸭子的博客 1万+

第二十七篇,LINUX系统编程开篇,进程的函数接口,包括创建进程fork(),查看进程的ID号getpid(),gedppid(),主动回收资源wait(),进程的退出exit() 函数。

一、linux系统编程学习大纲。 1、进程的概念、进程的诞生与死亡、进程基本函数接口,进程意义。 2、进程之间的通信方式:无名管道、有名管道、信号、消息队列、共享内存(信号量) 3、linux下信号集概念、信号集的函数接口、信号集作用、如何给信号集设置阻塞状态? 4、线程的概念、线程与进程有什么区别?线程诞生与死亡、线程一系列函数接口。 5、线程同步互斥方式:有名信号量、无名信号量、互斥锁、读写锁。 6、处理空闲线程的方式:条件变量。 7、线程池 -> 为了能够同时处理多个任务。

weixin_44651073的博客 505

概念解析 | 雷达动态范围

这里存在一个动态范围的问题:强雷达发射信号和弱目标反射信号存在非常大的功率差异,比如传统的脉冲多普勒雷达动态范围可达90dB以上。随着上述技术的发展,预计未来十年雷达接收机动态范围将达到120dB以上,届时雷达的监视能力将得到极大增强。简单来说,雷达动态范围越大,表示接收机噪声越低,对强信号过载保护能力越强,就越能检测到弱信号目标。此外,部分新概念雷达对动态范围提出新的需求,如被动雷达动态范围需大于100dB。当前,随着阵列雷达和数字雷达技术的发展,对雷达接收机动态范围提出了更高要求。

NLOS的博客 1051

【车载以太网】【架构】整体架构与协议标准

车载以太网架构图 应用层:DHCP /SOMEIP/DoIP/XCP/UDPNM 传输层:TCP/IP 网络层:IPv4/IPv6/ARP/ICMP 链路层:IEEE Ethernet MAC+VLAN 物理层:Ethernet PHY: 100BASE-T1/1000BASE-T1/100BASE-Tx

专注汽车软件开发、AutoSAR、车载以太网、SOA、EE架构。 8355

fork()创建子进程步骤、函数用法及常见考点(内附fork()过程图)

一个现有进程可以调用fork函数创建一个新的进程。 #include《unistd.h> pid_t fork(void);                    返回值:子进程中返回0,父进程中返回子进程的ID,出错返回-1 fork函数被调用一次,但返回两次。两次返回的唯一出别是child process的返回值是0,而父进程的返回值则是child process的进程ID。所以可以通

yangcs2009的专栏 2万+

定位精度再突破!Inner-MPDIoU让YOLOv11边界框回归更精准

Inner-MPDIoU 凭借辅助边框与最小点距离的双机制创新,彻底解决了传统 IoU 损失在边界框回归上的精度瓶颈。本教程从原理到代码实现,再到工业场景适配,完整呈现了其在 YOLOv11 中的集成路径。只需简单修改两处核心脚本,你的目标检测模型就能在边界框定位精度上实现跨越式提升——无论是学术研究中的指标突破,还是工业场景下的精细检测需求,Inner-MPDIoU 都能成为你攻克边界框回归难题的利器。现在就动手尝试,让你的检测模型在定位精度上再上一个台阶吧。

FJN110的博客 158

Linux系统级程序设计:fork()函数创建进程

注:本次学习代码所用编程那个语言为C语言 在Linux中我们使用fork()函数进行进程创建, 该函数包含在<unistd.h>中。 1. 父进程与子进程: fork()函数创建的进程为子进程。 调用fork()函数的进程称父进程。 2. fork()函数: pid_t fork(viod) // pid_t 相当于int类型 调用fork()函数过后, 系统会创建一个与原进程几乎相同的进程(感觉就像是将父进程的程序代码复制了一份给子进程),然后父子进程都继续往下执行。 fork()函数调

XP_DSB的博客 8158

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

fork()函数详解以及进程创建的过程

进程控制块(PCB):用来标识一个进程的,它包含了该进程的各个信息。它是task_struct这个结构体。 那这个task_struct结构体是怎样在内核中存在的呢?接下来我来说一下。 内核在为每一个进程分配PCB的时候,实际上是分配了两个连续的物理页面(共8K),这两个页面的底部1K空间用作进程的PCB结构,剩余7K就是这个进程的系统空间堆栈了,如图: 内核把进程的列表存放在任务队列的...

gaorutao0923的博客 1851

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

OS第二篇:进程创建fork()函数实验

    最近做了一次实验:     1.编写一段程序,利用系统调用fork()函数创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符串,其中,每个进程显示其pid值,及其父进程的pid值。(getpid返回当前进程标识,getppid返回父进程标识。)类似如下显示:父进程显示’"我是爸爸.pid:…爸爸的爸爸是ppid:… ",子进程分别显示’"...

H_W_1212的博客 4469

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Linux进程创建之fork()函数

进程创建 如何创建一个子进程 通过复制调用进程,创建一个新的进程,我们称这个新的进程为子进程。 复制的是父进程的PCB,因此父进程与子进程的关系就为代码共享,数据独有。 具体实现方法 通过调用fork()函数 函数原型 pid_t fork(void) 返回值 创建子进程成功,则有了两个进程,那我们如何对这两个进程进行区分呢,那便是通过fork()函数的返回值来判断,对于父进程返回...

zhangxu 658

进程创建函数fork()、vfork() ,以及excel()函数

一、进程的创建步骤以及创建函数的介绍1、使用fork()或者vfork()函数创建新的进程2、条用exec函数族修改创建的进程。使用fork()创建出来的进程是当前进程的完全复制,然而我们创建进程是为了让新的进程去执行新的程序,因此,就需要用到exec函数族对创建出来的新进程进行修改,让他拥有和父进程不一样的东西,修改后就可以执行新的程序,当然,修改后的子进程包含了要执行程序的信息。在

gc315630的专栏 1万+

fork()函数如何创建进程?【详细步骤】

以上程序调用fork()函数创建子进程,使用变量value记录fork()的返回值,并根据fork()的返回结果区分父进程与子进程,为这两个进程分派不同的任务:当value为0时,说明当前进程是子进程,执行if分支中的语句;以上函数调用后,操作系统会建立当前线程的副本以实现进程的创建,此时原有的进程被称为父进程,复制的进程被称为子进程。从图2中可以看出,“父进程1”和“子进程1”再次复制出两个子进程,“父进程1”成为“子进程2”的父进程,“子进程1”成为“子进程3”的父进程,变成“父进程2”。

zy1992As的博客 2572

Linux中fork()函数创建进程

Linux系统中学习fork函数创建进程前言一.准备工作二.任务三.感想 前言    最近学习到操作系统原理中的进程同步的知识点时,为了加深对进程的了解,就实践了一下在Linux系统中fork()函数的使用。 一.准备工作    装有Linux系统的电脑 二.任务 三.感想    作为一个Linux系统新手,刚开始看fork()函数时也是很懵逼的,也是看了好多博客才逐渐明白的,很感谢那些将自己的心...

weixin_42616278的博客 1万+

Fork() 函数:“父” 与 “子” 进程的交互(进程的创建)

本文介绍了fork函数的基本概念和写时拷贝机制。fork函数是用于创建子进程的系统调用,通过复制父进程的地址空间实现子进程的创建。而写时拷贝机制则是一种优化策略,只有在需要修改共享内存时才进行复制操作,从而减少资源消耗和提高性能。文章通过解释fork函数的返回值和写时拷贝的原理,帮助读者理解fork函数的工作方式,并在编写多进程程序时进行性能优化。

Yawesh的博客 5042

linux下操作系统关于用fork()函数创建进程相关的问题

今天在Linux系统下用fork()函数创建进程,fork()函数会返回一个int型的值,若在父进程,则fork()函数返回值>0,如果是在子进程中,则会返回0,若fork()函数返回值为-1,则代表创建进程失败。 用fork创建两个子进程后,若是父进程则打印‘a’,若是第一个子进程,打印‘b’,若是第二个子进程,则打印‘c’,经过大量实验证明,用fork()函数创建线程,cpu总是会先去.........

qq_42152681的博客 1196

fork()函数和进程创建

使用fork()函数创建进程,研究子进程和父进程之间的关系

weixin_63851915的博客 802

Linux下进程创建Fork()函数分析

一个进程包括代码、数据、进程控制块、堆栈等资源。进程在运行时还有自身的状态,这个自身的状态不是指宏观上的就绪态、等待态,而是指进程在CPU上运行时,CPU内部各个寄存器的值,进程在切换的时候,这些状态值是要保存在堆栈当中的,目的是下次进程运行时能够“无缝”连接。 Linux下,用于创建进程的函数是fork()函数。fork()函数创建的“子进程是父进程的一个完整拷贝”,也就是说子进程和父进程基本

yangkuiwu的博客 1526

对于创建进程函数fork()的深度剖析

用了很多次fork()函数,但是很少会对这个函数深入了解过,导致了项目程序上出了一点错误,看了一些资料,做以下总结。 首先,是fork()函数的作用以及用法。 fork调用一次以后,能够返回两次,它可能有三种不同的返回值: 1)在父进程中,fork返回新创建子进程的进程ID; 2)在子进程中,fork返回0; 3)如果出现错误,fork返回-1; 在fork函数执行完毕后,如果创建新进程成功,则出...

Zhang_S_Q的博客 598

创建进程-fork()函数

fork()的作用是创建一个子进程。

qi琪的专栏 1761
上一篇: 单链表详解
下一篇: fork()函数的面试题
IT_model
博客等级 码龄9年 61粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值