【Linux】-进程概念及初始fork

news2024/9/28 23:32:15

在这里插入图片描述
💖作者:小树苗渴望变成参天大树🎈
🎉作者宣言:认真写好每一篇博客💤
🎊作者gitee:gitee✨
💞作者专栏:C语言,数据结构初阶,Linux,C++ 动态规划算法🎄
如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧!

文章目录

  • 前言
  • 一、进程标识符
    • 1.1认识第一个系统调用接口
    • 1.2 第二个系统调用接口fork
  • 二、总结


前言

上篇Linux我们讲解了什么是进程,从硬件,在到软件,再到宏观上讲解了操作系统是怎么管理我们软硬件的,大家应该已经有了一定的认识和了解,今天我们就对进程展开来讲点东西,我们的在Windows这样的操作系统是使用PCB来这个的结构体形成的结构去管理的,但在Linux上我们是task_struct结构体去管理我们的软硬件的,那我们结构体里面到底有什么,在上节课我们只是把具体的属性给大家展示了,但是并不知道什么意思,今天我们先介绍其中一点,话不多说,我们开始进入正文。


task_ struct内容分类

标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
上下文数据: 进程执行时处理器的寄存器中的数据。
I/O状态信息: 包括显示的I/O请求分配给进程的I/O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
其他信息


fork一会再说,先做一个知识铺垫。

一、进程标识符

我们上篇的最后讲解了怎么去看一个进程,我们来写一个死循环的程序,防止他很快就结束进程,不方便我们去查看他的进程

   #include<stdio.h>
   #include<unistd.h>
   int main()
   {
       while(1)
       {
          printf("我是一个进程\n");
          sleep(1);                                                              
      }
      return 0;
  }

第一:通过proc这个文件夹去看,但是这种方法不知道对应的是哪个进程。
在这里插入图片描述
第二种:通过命令查看ps ajx | head -1 && ps ajx | grep proc或者ps ajx | head -1 && ps ajx | grep proc | grep -v grep
在这里插入图片描述
我们的进程task_struct就是一个结构体类型的结点,ps的作用实际就是在遍历这个结构,通过grep把找到的过滤出来。我们发现一个进程有这么多个属性,我们值需要了解其中两个,其余的不重要,一个是PID(进程id),一个是PPID(父进程id),后面会介绍到这两者有什么关系

1.1认识第一个系统调用接口

在这里插入图片描述
通过计算机层状结构图,我们知道了系统调用接口是直接对接操作系统的,系统调用接口也是一个函数,一会学习的两个接口就是来查看PID和PPID的,我们来看代码:

   #include<stdio.h>
   #include<sys/types.h>
   #include<unistd.h>
   int main()
   {
       while(1)
       {
          printf("我是一个进程,PID:%d,PPID:%d\n",getpid(),getppid());
		//这两个系统调用接口都是一个无参函数,哪个程序去调用就返回谁的PID和PPID
          sleep(1);                                                              
      }
      return 0;
  }

我们来写一个命令当成监视窗口:while :; do ps ajx | head -1 ; ps ajx | grep proc | grep -v grep ; sleep 1 ; done 这是每个1秒显示一个进程信息。

在这里插入图片描述
大家看到我们通过系统调用接口也把我们的id给获取到了。

大家应该会发现,我将自己写的程序运行了两次,PID两次都不同,PPID却是相同的,这是为什么呢?我们来看看这个程序PPID是什么。
在这里插入图片描述

这个程序的PPID是我们bash程序的PID,bash不就是我们之前说的王婆,这就是一个外壳程序,命令行解释器,是我们每次登录的时候,Linux操作系统自动就会运行这个bash程序形成了一个进程,我们写的程序就是在这个进程创建的基础下跑,当我们再次登录这个bash进程的PID又会发生变化,而我们自己写的程序每次运行的PID不一样是正常的,就好比你刚进校的学号,每个人第二次考上进去的学号都是不一样的。

通过上面的解释,操作系统是不会让你直接去在他的进程上创建子进程去运行的,是通过bash进程,我们写的程序就是他的子进程,在bash进程下创建子进程去跑的,为什么要这么做,接下来我们讲到fork就可以来解决我刚才说的问题

1.2 第二个系统调用接口fork

这个接口就可以让我们更好的认识父子进程的关系,以及上面的操作是怎么做到的,我们先来看一个例子:

在这里插入图片描述
大家看到我们加了fork之后,居然打印了两次,这个例子还不能说明什么,我们来看看文档
在这里插入图片描述
这个返回值看上去非常的抽象,是要返回两个值??太不可思议了,我们再来看一个例子:
在这里插入图片描述
我们看到两个死循环都走起来了,这下更不可思议了。一个程序怎么会执行两个死循环语句呢?接下来我将通过四个问题来带大家解决疑惑:

  1. 为什么fork需要给子进程返回0,给父进程返回子进程的PID
    (1)为什么要返回不同的值,是为了区分让不同的执行流,去执行不同的代码块,就好比上面的代码。
    (2)每个父进程可以有好多个子进程,子进程只有一个父进程,所以父进程需要知道子进程的PID来唯一标识要控制哪个子进程去执行。而返回0是为了标识子进程,子进程通过getppid就可以找到父进程

  2. fork干了什么事情?
    在这里插入图片描述

这下大家应该知道为什么要返回两次,是如何做到分流的吧,但是fork是一个函数,怎么做到返回两次呢??

  1. 一个函数是如何做到返回两次的??
    在这里插入图片描述

写时拷贝: **大家应该知道我们在Windows上,我们启动了许多个软件,但其中一个软件挂掉了会不会影响其他软件,答案是不会的,所以在任何平台上,进程在运行的时候,是具有独立性的**,那我们刚才说到fork他也是创建一个子进程,在上面我们说到,父子进程的代码和数据是共享的,那么就会导致如果子进程修改了数据,那么可能会影响到我父进程的运行,此时就不符合进程具有独立性的思想,想问一下大家,代码共享而数据不共享是不是具有独立性:答案是具有,因为你的代码最终操控都是数据,只要操作的数据不是一样的就不会影响到其他进程的运行,所以防止这种事情的发生,我们父子进程的代码时共享,数据不共享,如下图:
在这里插入图片描述
将父进程的数据拷贝到新的空间个给子进程自己玩,就算子进程修改了数据也是他那一块空间的数据,不会影响到父进程对应的数据,就实现了进程之间的独立性。


此时又面临一个问题:当内存空间严重不足时,我们父进程还是把所有的数据都拷贝到子进程的数据空间里吗?如果子进程没有使用这些数据,那么不就造成资源浪费了吗??内存要想办法给自己节省空间,所以此时就引入了写时拷贝这个概念,我们的父子进程一开始还是指向同一块数据的,如果子进程想要修改数据,内存在给其分配空间,将要修改的数据先拷贝到新空间,然后你在修改,这样就做到了用多少拷多少。
在这里插入图片描述
这就好比C++说的深浅拷贝,你要想看看数据,指向同一块空间也无所谓,但你要想修改内容,我给你在开辟一块空间,你修改了不能影响到我原来的数据。

有了上面的写时拷贝,我们再来谈谈fork函数返回值的问题,上面只是说到怎么返回两次的,父子进程分别去调用return就可以了,那怎么做到返回不同的值,原因就是return语句是写入,写入就要修改数据,此时内存就会将返回的数据拷贝到子进程的新数据区中,然后让子进程进行修改在返回,所以我们会返回两个同的值。


在这里插入图片描述通过上面的例子,我们发现bash进程也应该是操作系统fork出来的子进程,那我们的操作系统为什么要这么做,因为我们的操作系统也是一款软件,在内存中也有自己的进程,他不相信任何用户,所以他需要创建子进程,用户想要修改数据,修改的是子进程指向的数据空间,修改了不会影响我操作系统进程指向的数据空间,这样就保证了操作系统的安全性

相信此时大家对fork的理解又加深了,并且了解父子进程的关系了吧。

  1. 一个变量是如何接收两个不同的值
    这个需要使用到我们进程地址空间的知识,但是此时已经不影响我们对fork以及父子进程的理解了,而且也知道fork的作用以及目的。

如果父子进程被创建好,fork()往后,哪个进程先运行呢?

谁先运行是由调度器去决定,调度器有自己的调度算法,这个在后面的博客会介绍到,他是怎么去调度的,目前我们上面这个问题是不知道答案的,不确定谁先被执行。

通过上面四个问题的解释,我来给fork做一个小总结:

  1. fork有两个返回值
  2. 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)
  3. fork 之后通常要用 if 进行分流

二、总结

通过这节的学习,我们知道了fork这个系统接口的用法,以及作用,可以说这个接口对我们的学习是又很大的帮助,可以使我们分别去做不同的事,也让我们知道函数还有又这样的功能,是我们的认知又提高了一个档次,接下来的一篇我还是介绍task_struct里面的属性-进程状态。一起来期待吧
请添加图片描述

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

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

相关文章

C++ 拷贝构造函数

拷贝构造函数是一种特殊的构造函数&#xff0c;具有一般构造函数的所有特性&#xff0c;其形参是本类的对象的引用。其作用是使用一个已经存在的对象&#xff08;由拷贝构造函数的参数指定&#xff09;&#xff0c;去初始化同类的一个新对象。 如果程序员没有定义类的拷贝构造函…

自动驾驶感知系统--惯性导航定位系统

惯性导航定位 惯性是所有质量体本身的基本属性&#xff0c;所以建立在牛顿定律基础上的惯性导航系统&#xff08;Inertial Navigation System,INS&#xff09;(简称惯导系统)不与外界发生任何光电联系&#xff0c;仅靠系统本身就能对车辆进行连续的三维定位和三维定向。卫星导…

Ubuntu-文件和目录相关命令一

&#x1f52e;linux的文件系统结构 ⛳目录结构及目录路径 &#x1f9e9;文件系统层次结构标准FHS Filesystem Hierarchy Standard(文件系统层次结构标准&#xff09; Linux是开源的软件&#xff0c;各Linux发行机构都可以按照自己的需求对文件系统进行裁剪&#xff0c;所以众多…

MyBatisPlus从入门到精通-3

紧接着上一篇的查询 接下来的重点介绍增删改操作了 Insert id&#xff08;主键&#xff09;生成策略 前面的案列中我们没有指定id字段 但是它是生成了一个很长的id&#xff0c;并不是我们数据表定义自增 这是Mp内部算法出来的一个值 其实根据不同应用场景&#xff0c;应该使…

抖音SEO源代码的部署与搭建技巧详解

抖音SEO源代码的部署与搭建是一项重要的技术&#xff0c;促进了抖音的发展。在此&#xff0c;我将为大家详细介绍抖音SEO源代码的部署与搭建技巧。 首先&#xff0c;我们需要了解抖音SEO源代码的含义。SEO源代码是搜索引擎优化的核心&#xff0c;它是用于帮助搜索引擎更好地理解…

PHP使用Redis实战实录3:数据类型比较、大小限制和性能扩展

PHP使用Redis实战实录系列 PHP使用Redis实战实录1&#xff1a;宝塔环境搭建、6379端口配置、Redis服务启动失败解决方案PHP使用Redis实战实录2&#xff1a;Redis扩展方法和PHP连接Redis的多种方案PHP使用Redis实战实录3&#xff1a;数据类型比较、大小限制和性能扩展 数据类型…

pytorch的发展历史,与其他框架的联系

我一直是这样以为的&#xff1a;pytorch的底层实现是c(这一点没有问题&#xff0c;见下边的pytorch结构图),然后这个部分顺理成章的被命名为torch,并提供c接口,我们在python中常用的是带有python接口的&#xff0c;所以被称为pytorch。昨天无意中看到Torch是由lua语言写的&…

docker 部署 mysql8.0 无法访问

文章目录 &#x1f5fd;先来说我的是什么情况&#x1fa81;问题描述&#x1fa81;解决方法&#xff1a;✔️1 重启iptables✔️2 重启docker &#x1fa81;其他有可能连不上的原因✔️1 客户端不支持caching_sha2_password的加密方式✔️2 my.conf 配置只有本机可以访问 &#…

用JavaScript和HTML实现一个精美的计算器

文章目录 一、前言二、技术栈三、功能实现3.1 引入样式3.2 编写显示页面3.2 美化计算器页面3.3 实现计算器逻辑 四、总结 一、前言 计算器是我们日常生活中经常使用的工具之一&#xff0c;可以帮助我们进行简单的数学运算。在本博文中&#xff0c;我将使用JavaScript编写一个漂…

【我们一起60天准备考研算法面试(大全)-第二十八天 28/60】【枚举】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

VBA技术资料MF35:VBA_在Excel中过滤数据

【分享成果&#xff0c;随喜正能量】好马好在腿&#xff0c;好人好在嘴。不会烧香得罪神&#xff0c;不会讲话得罪人。慢慢的你就会发现&#xff0c;一颗好心&#xff0c;永远比不上一张好嘴。。 我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#…

Android实例——自定义控件

自定义View 对现有控件进行扩展 案例一&#xff1a;添加背景 如下继承TextView public class MyTextView extends androidx.appcompat.widget.AppCompatTextView {private Paint mPaint1;private Paint mPaint2;public MyTextView(Context context) {this(context, null);}…

wireshark抓包新手使用教程(超详细)

一、简介 Wireshark是一款非常流行的网络封包分析软件&#xff0c;可以截取各种网络数据包&#xff0c;并显示数据包详细信息。 为了安全考虑&#xff0c;wireshark只能查看封包&#xff0c;而不能修改封包的内容&#xff0c;或者发送封包。 wireshark能获取HTTP&#xff0c;也…

day47-Testimonial Box Switcher(推荐箱切换器-动态进度条自动更新卡片信息)

50 天学习 50 个项目 - HTMLCSS and JavaScript day47-Testimonial Box Switcher&#xff08;推荐箱切换器-动态进度条自动更新卡片信息&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"…

Docker续集+Docker Compose

目录 Containerd与docker的关系 runCrunC与Containerd的关联 OCI协议Dockerfile多阶段构建&#xff08;解决&#xff1a;如何让一个镜像变得更小 &#xff09;多阶段构建Images瘦身实践.dockerignore Docker Compose快速开始Quick StartCompose 命令常用命令命令说明 Compose 模…

11. Mybatis 的增删查改【万字详解】

目录 1. 数据的查找 select 1.1 查询所有数据 1.2 通过 id 进行查找 2. 插入数据 insert 3. 修改数据 update 4. 删除数据 delete 5. $ 和 # 的区别 5.1 SQL 注入 用户登录 6. Spring Boot 打印 SQL 日志 7. order by 排序 8. like 查询 9. 通过页面返回数据 10. …

C++--菱形继承

1.什么是菱形继承 单继承&#xff1a;一个子类只有一个直接父类时称这个继承关系为单继承 多继承&#xff1a;一个子类有两个或以上直接父类时称这个继承关系为多继承 菱形继承的问题&#xff1a;菱形继承有数据冗余和二义性的问题&#xff0c;数据冗余是由于创建多个相同类型的…

【C++】优先级队列的基本概念以及其模拟实现

文章目录 补充知识&#xff1a;仿函数一、优先级队列&#xff1a;1.引入2.介绍 二、priority_queue的模拟实现1.大体框架2.私有成员函数&#xff1a;1.向下调整&#xff08;AdjustDown&#xff09;2.向上调整&#xff08;AdjustUp&#xff09; 3.公有成员函数1大小&#xff08;…

Windows驱动第一节(什么是驱动?)

本文来自微软,由本人兴趣爱好人工翻译(非机翻) What is a driver? - Windows drivers | Microsoft Learn 我想很难给驱动这个词一个准确的定义.最基础的定义是驱动是一个用于让操作系统和硬件设备通信的软件组件. 举一个例子,假设一个应用程序需要从硬件设备读取一些数据,这…

2023河南萌新联赛第(三)场:郑州大学 A - 发工资咯

2023河南萌新联赛第&#xff08;三&#xff09;场&#xff1a;郑州大学 A - 发工资咯 时间限制&#xff1a;C/C 2秒&#xff0c;其他语言4秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld 题目描述 一个公司有n个人&#xff0c;每个月都…