当前位置: 首页 > news >正文

Linux进程——进程的创建(fork的原理)

前言:在上一篇文章中,我们已经会使用getpid/getppid函数来查看pid和ppid,本篇文章会介绍第二种查看进程的方法,以及如何创建子进程!


在这里插入图片描述


本篇主要内容:

  • 查看进程的第二种方法
  • 创建子进程
  • 系统调用函数fork

在这里插入图片描述


在开始前,我先来回顾一下如何获取pid,ppid
在这里插入图片描述

进程要想区分就一定会有唯一的标示符,而pid,ppid初始化后就变为内核中的数据,也就是操作系统里的数据,在我们自己开发时,操作系统不会将内部数据暴露出来,不能直接访问,所以通过系统调用接口直接获取pid,ppid。

目录

  • 1. 查看进程的第二种方法
  • 2. 创建子进程
    • 2.1 系统调用函数fork
    • 2.2 fork的一般写法
    • 2.3 fork的原理
  • 3. 总结


1. 查看进程的第二种方法

在Linux系统中,不只有ps能够查看进程,还存在着一个动态目录proc,该目录存放了所有存在的进程,目录的名称。它会随着进程的改变而随时更新它的内容!

查看所有进程:
指令:ls /proc/

在这里插入图片描述

查看指定pid的进程文件:
指令:ls /proc/进程pid

如果想只查看这个目录我们可以:
指令:ls /proc/进程pid -dl

proc查看进程

当我们结束这个进程时,文件也会从proc中被删除


误删可执行程序时

在看完这个视频后,我们发现当我们在程序运行时,误删了可执行程序,进程不会被终止,但是在proc目录中的exe被标红并注明delete

在自行创建的进程中,我们只需要掌握好两个文件cwdexe

  • cwd代表当前工作目录
  • exe指向可执行程序的位置

默认情况下,进程启动所处的路径,就是当前路径,pwd指令其实就是从cwd中找到当前路径的!

当前工作目录是可以通过系统调用进行修改的:
指令:chdir ( " 路径 " )

我们只需要在代码编写时,加入这条指令我们就能更改当前工作目录


2. 创建子进程

2.1 系统调用函数fork

在Linux中,进程的创建方式有两种:

  • 命令行中直接启动进程
  • 通过代码创建

而在用代码创建进程时,实则是进行了系统调用,这里我们就得在学习一个系统调用函数fork!

函数:fork

让我们来简单用man指令了解fork函数信息
在这里插入图片描述
fork的功能是创建一个子进程
让我们来简单实现以下fork
在这里插入图片描述

在这里插入图片描述
我们发现在fork之后函数printf调用了两次!!!

我们再来看看进程的ppid
在这里插入图片描述
在这里插入图片描述

  • 说明了一个情况:fork之后,会创建子进程,并且子进程会和父进程一起进入后面的函数并且分别执行一次

2.2 fork的一般写法

结合目前: 只有父进程执行fork之前的代码(一定),fork之后,父子进程都要执行后续的代码!

  • 因此我们推断fork函数不仅会帮我们创建子进程而且它还有两个返回值,fork成功的时候,会有两个不同的返回值,给子进程返回0,给父进程返回子进程的pid。

首先我们来思考以下问题:

那么我们为什么要创建子进程?子进程的作用是啥?

  • 我们想让子进程协作父进程完成一些工作,这些工作是单进程解决不了的,因此子进程的创建是为了协助父进程,因此父子进程做的是不一样的事情

我们怎么保证父子进程做的是不一样的事情呢?

  • 我们可以通过判断fork的返回值,判断谁是父,谁是子,然后让他们执行不同的代码片段

让我们来看一下fork的一般写法

  1 #include<stdio.h>2 #include<sys/types.h>3 #include<unistd.h>4 5 int main()6 {7     printf("i am a process, 我的pid: %d\n", getpid());8 9 10     pid_t id = fork();11                                                                               12     if(id < 0) return 1;13 14     else if(id == 0)15     {16         // child17         while(1)18         {19             printf("我是子进程: pid: %d, ppid: %d, ret: %d, 我正在执行下载任务    \n",getpid(),getppid(),id);20             sleep(1);21         }22     }23 24     else25     {26         // parent27         while(1)28         {29             printf("我是父进程: pid: %d, ppid: %d, ret: %d, 我正在执行播放任务    \n",getpid(),getppid(),id);30             sleep(1);31         }32     }33 }

在这里插入图片描述
我们可以看到明明我们的fork只使用了一个变量接收但是出现了两个返回值

2.3 fork的原理

关于fork这个函数的原理,我们依然抛出几个问题

  1. fork干了什么事情?
  2. 为什么fork会有两个返回值?
  3. 为什么fork的两个返回值,会给父进程返回子进程pid,给子进程返回0?
  4. fork之后父子进程谁先运行?
  5. 如何理解同一个变量会有不同的值?

fork干了什么事情?

fork创建子进程,系统中会多一个子进程

  • 以父进程为模板,为子进程创建PCB
  • 但是你今天创建的子进程,是没有代码和数据的!!!目前和父进程共享代码和数据!!
  • 所以,fork之后,父子进程会执行一样的代码

在这里插入图片描述


为什么fork的两个返回值,会给父进程返回子进程pid,给子进程返回0?

在用进程中,一个父进程可能会有多个子进程,但是子进程永远都只有一个父进程,所以父 :子 只会是 1 :n,为了能够更好的管理这些子进程,就必须返回具有唯一性的pid。但是子进程会很容易找到父进程,所以返回0表示成功即可!!


fork之后父子进程到底谁先运行?

创建完成子进程,只是一个开始,创建完成子进程之后,系统的其他进程,父进程和子进程,接下来要被调度执行的,当父子进程的PCB都被创建并在运行队列中排队的时候,哪一个进程的PCB先被选择调度,那个进程就先运行!!

  • 但是PCB的选择调度是由操作系统自主决定(由各自PCB中的调度信息(时间片,优先级等)+调度器算法共同决定)
  • 所以我们不确定父子进程到底谁先运行

最后为什么fork会有两个返回值?

如果一个函数到达了return,那么他的核心工作是否完成?

  • 答案很显然是的,所以。。。

在这里插入图片描述
最后在fork之后代码共享,所以return也会被共享进入父子进程,并在父子进程中分别执行,所以在fork函数return之前,父子进程就已经分流,因此就会产生两个返回值!


如何理解同一个变量会有不同的值?

同一个函数有两个返回值是因为fork后两个进程都被调度了,但是同一个变量会有不同的值?该如何理解?

首先我们思考一下,如果我们杀掉子进程,父进程还会存在嘛?杀掉父进程呢?

分析父子进程是否独立

由此,我们可以得出结论:进程之间运行的时候,是具有独立性的,杀掉父进程不会影响子进程!反之也是!

  • 进程的独立性,首先是表现在有各自的PCB进行之间不会互相影响,代码本身是只读的,不会影响,数据父子是会修改的!代码共享,数据各个进程都会写时拷贝私有一份!
  • 变量id是父进程定义的变量,保存数据,返回的时候发生写时拷贝,不同
    的进程执行的代码中的变量id获取的值不同,所以id在父进程和子进程中值不同

3. 总结

fork函数的内容远不只有这么一点,但是理解这五个问题能快速帮助我们,简单理解这个函数,了解fork的原理!关于如何创建子进程我们就讲到这里!

谢谢大家支持本篇到这里就结束了
在这里插入图片描述

相关文章:

Linux进程——进程的创建(fork的原理)

前言&#xff1a;在上一篇文章中&#xff0c;我们已经会使用getpid/getppid函数来查看pid和ppid,本篇文章会介绍第二种查看进程的方法&#xff0c;以及如何创建子进程&#xff01; 本篇主要内容&#xff1a; 查看进程的第二种方法创建子进程系统调用函数fork 在开始前&#xff…...

ICode国际青少年编程竞赛- Python-1级训练场-路线规划

ICode国际青少年编程竞赛- Python-1级训练场-路线规划 1、 Dev.step(3) Dev.turnLeft() Dev.step(4)2、 Dev.step(3) Dev.turnLeft() Dev.step(3) Dev.step(-6)3、 Dev.step(-2) Dev.step(4) Dev.turnLeft() Dev.step(3)4、 Dev.step(2) Spaceship.step(2) Dev.step(3)5、…...

uniapp微信小程序1rpx border在某些手机机型上边框显示不出来解决方案

小程序在ios系统中&#xff0c;如果border小于1px的情况下&#xff0c;border就可能显示不全(可能少了上下左右任意一边) 只需要加一个::after或::before伪类&#xff0c;使用绝对定位定在原来元素上边就不会产生问题了&#xff01; .d_card_line1_tag { padding: 1rpx 14r…...

Linux mkfs.ext2命令教程:如何创建ext2文件系统(附实例详解和注意事项)

Linux mkfs.ext2命令介绍 mkfs.ext2是Linux系统中用于创建ext2文件系统的命令。它的作用是在指定的设备上创建一个ext2文件系统&#xff0c;使该设备能够存储文件和目录。创建ext2文件系统的过程包括以下几个步骤。 Linux mkfs.ext2命令适用的Linux版本 mkfs.ext2命令在大多…...

基于Springboot的校园招聘系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园招聘系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…...

将 Vue、React、Angular、HTML 等一键打包成 macOS 和 Windows 平台客户端应用

应用简介 PPX 基于 pywebview 和 PyInstaller 框架&#xff0c;构建 macOS 和 Windows 平台的客户端。本应用的视图层支持 Vue、React、Angular、HTML 中的任意一种&#xff0c;业务层支持 Python 脚本。考虑到某些生物计算场景数据量大&#xff0c;数据私密&#xff0c;因此将…...

使用 MobaXterm 链接 Ubuntu(Windows子系统)

MobaXterm_Personal_22.1 Ubuntu&#xff08;Windows子系统&#xff09;...

QT设计模式:代理模式

基本概念 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许你提供一个代理对象&#xff0c;以控制对其他对象的访问。 代理通常在客户端和实际对象之间充当中介&#xff0c;用于控制对实际对象的访问&#xff08;如登录控制&#xff09;…...

独热编码One-Hot是什么?在实际应用中具体是如何存储的?

One Hot编码是一种常用的文本或类别数据编码方式&#xff0c;尤其在自然语言处理和机器学习中。在One Hot编码中&#xff0c;每个词&#xff08;或类别&#xff09;会被表示为一个二进制的向量&#xff0c;这个向量的长度等于词汇表&#xff08;或类别总数&#xff09;的大小&a…...

计算机视觉与深度学习实战之以Python为工具:基于GUI搭建通用视频处理工具

注意:本文的下载教程,与以下文章的思路有相同点,也有不同点,最终目标只是让读者从多维度去熟练掌握本知识点。 下载教程:计算机视觉与深度学习实战-以MATLAB和Python为工具_基于GUI搭建通用视频处理工具_项目开发案例教程.pdf 一、引言 随着计算机视觉和深度学习技术的飞速…...

18.Docker学习

1.Docker应用场景 Docker借鉴了标准集装箱的概念。标准集装箱将货物运往世界各地&#xff0c;Docker&#xff08;模板&#xff09;将软件运往各个环境&#xff08;测试环境和生产环境拉取镜像&#xff08;实例&#xff09;&#xff09;&#xff0c;相当于是一个模子刻出来的 …...

树莓派4b红外检测

1.红外检测连接图 2.红外检测工作原理 红外传感器的工作原理类似于物体检测传感器。该传感器包括一个红外LED和一个红外光电二极管&#xff0c;因此通过将这两者结合起来&#xff0c;可以形成一个光耦合器。 红外LED是一种发射红外辐射的发射器。该LED看起来与标准LED相似&a…...

大模型的不足与解决方案

文章目录 ⭐ 不具备记忆能力 上下文窗口受限⭐ 实时信息更新慢 新旧知识难区分⭐ 内部操作很灵活 外部系统难操作⭐ 无法为专业问题 提供靠谱的答案⭐ 解决方案的结果 各有不同的侧重 在前面三个章节呢&#xff0c;为大家从技术的角度介绍了大模型的历程与发展&#xff0c;也为…...

Java中使用FlatBuffers实现序列化

Java 中的 FlatBuffers有助于高速数据序列化/反序列化&#xff0c;消除解析开销。它由 Google 开发&#xff0c;为跨平台数据交换提供无模式、内存高效的解决方案。 Java 开发人员可以利用其直接内存访问来实现最佳性能和最小内存占用&#xff0c;从而提高应用程序速度、可扩展…...

[图解]SysML和EA建模住宅安全系统-02

1 00:00:00,900 --> 00:00:02,690 这个就是一个块定义图了 2 00:00:03,790 --> 00:00:04,780 简称BDD 3 00:00:05,610 --> 00:00:08,070 实际上就是UML里面的类图 4 00:00:08,080 --> 00:00:09,950 和组件图的一个结合体 5 00:00:13,150 --> 00:00:14,690 我…...

2024年北京服贸会媒体邀约资源有哪些?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 2024年北京服贸会&#xff08;中国国际服务贸易交易会&#xff0c;简称CIFTIS&#xff09;作为中国重要的国际性服务贸易盛会&#xff0c;会吸引众多媒体的关注和参与。媒体邀约资源通常…...

大语言模型LLM入门篇

大模型席卷全球&#xff0c;彷佛得模型者得天下。对于IT行业来说&#xff0c;以后可能没有各种软件了&#xff0c;只有各种各样的智体&#xff08;Agent&#xff09;调用各种各样的API。在这种大势下&#xff0c;笔者也阅读了很多大模型相关的资料&#xff0c;和很多新手一样&a…...

Alibaba Cloud Linux 安装mysql及注意事项

1.安装mysql #1.运行以下命令&#xff0c;更新YUM源。 sudo rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm#2.&#xff08;可选&#xff09;当操作系统为Alibaba Cloud Linux 3时&#xff0c;执行如下命令&#xff0c;安装MySQL所需的库文件…...

设计模式——工厂模式(Factory)

工厂模式&#xff08;Factory Pattern&#xff09;是一种常用的设计模式&#xff0c;它提供了一种封装创建对象过程的方法。通过工厂方法或工厂类&#xff0c;你可以将对象的创建与使用分离&#xff0c;使得代码更加灵活和可维护。工厂模式主要分为三种类型&#xff1a;简单工厂…...

NVIDIA Omniverse Cloud API支持数字孪生开发,可解决复杂AI问题 | 最新快讯

在全球范围内&#xff0c;价值超过 50 万亿美元的重工业市场&#xff0c;正在竞相实现数字化。 基于此&#xff0c;为帮助数字孪生技术更好地赋能千行百业&#xff0c;AI 企业 NVIDIA 在架构底层算力的同时&#xff0c;也搭建了 NVIDIA AI Enterprise 和 Omniverse 两大平台。 …...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...