Linux--进程(1)

目录

前言

1.冯诺依曼体系结构

2. 操作系统(Operator System)--第一个被加载的软件

3.进程 

3.1基本概念 

 3.2Linux中的PCB

 3.3通过系统调用创建子进程-fork初识

fork:创建一个子进程

为什么要创建子进程?

fork的原理:

进一步了解fork的返回值

demo代码(一次创建多个子进程)


前言

在学习进程之前,我们要明白先了解两个东西:

                                1.体系结构----硬件上

                                2.操作系统----软件上


1.冯诺依曼体系结构

我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。

截至目前,我们所认识的计算机,都是有一个个的硬件组件组成

  • 输入单元:包括键盘, 鼠标,扫描仪, 写板等
  • 中央处理器(CPU):含有运算器和控制器等
  • 输出单元:显示器,打印机,磁盘,显卡,网卡,声卡等

关于冯诺依曼,必须强调几点:

  • 这里的存储器指的是内存(掉电易失)
  • 不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)
  • 外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。
  • 一句话,所有设备都只能直接和内存打交道。

再谈一个问题,为什么在体系结构中要有内存?

        冯诺依曼体系结构中要有内存,主要是因为内存可以适配CPU与外设之间速度不匹配的问题,从而提高整机效率。
        在冯诺依曼体系结构中,CPU的速度最快,而输入输出设备是最慢的。这会导致从输入设备传入数据到CPU处理,再从CPU传出已处理的数据到输出设备,这些过程之间的速度不匹配问题,降低了整机效率。为了解决这个问题,冯诺依曼体系引入了内存的概念。
        内存具有数据存储的能力,可以提前把数据准备好,CPU只需要从内存中拿数据进行处理。此外,根据局部性原理,当CPU需要获取某一行数据时,内存可以将该行数据之后的数据一同加载进来,而CPU处理数据和内存加载数据是可以同时进行的,这样下次CPU就可以直接从内存当中获取数据。
        因此,内存作为计算机数据的核心,可以大大提高数据处理的效率和速度。引入内存就把,效率问题,转化为了软件问题。

场景:

程序在运行的时候必须把程序先加载到内存中,为什么?

程序最终都是文件,文件都存储在硬盘上,硬盘属于外设;程序运行所产生的指令和数据,最终是要让cpu执行的;存储在硬盘中的程序(外设)最终会交给内存,是因为在数据层面,cpu只和内存交互,程序需要加载到内存中,再由内存交给cpu处理,这是冯诺依曼体系结构这么规定的。


对冯诺依曼的理解,不能停留在概念上,要深入到对软件数据流理解上,请解释,从你登录上qq开始和某位朋友聊天开始,数据的流动过程。 从你打开窗口,开始给他发消息,到他的到消息之后的数据流动过程。如果是在qq上发送文件呢?
 聊天的时候,键盘输入的信息储存在内存中,并将其打包成特定的网络协议格式。CPU对这些数据进行处理,确保它们可以正确地通过网络发送。这些数据包通过网络发送到朋友的计算机上。朋友的计算机上的QQ程序处理这些接收到的消息,将其解包并显示在屏幕上。

如果是发送文件,这个文件首先被从硬盘读取到内存中。再以同样的方式发送到朋友那,朋友接收后,QQ程序处理这些数据包,去掉头信息,并将它们重新组装成原始的文件。这个文件随后被存储在朋友的计算机的硬盘上,朋友可以在其计算机上访问和查看这个文件。

这个过程内存也是起着核心作用。


2. 操作系统(Operator System)--第一个被加载的软件

 任何计算机系统都包含一个基本的程序集合,称为操作系统。笼统的理解操作系统包括:

  • 内核(进程管理,内存管理,文件管理,驱动管理)
  • 其他程序(例如函数库, shell程序等等)

设计OS的目的:

  • 与硬件交互,管理所有的软硬件资源
  • 为用户程序(应用程序)提供一个良好的执行环境

定位:在整个计算机软硬件架构中,操作系统的定位是: 一款纯正的“搞管理”的软件
在这里我们引入一张图:计算机的层状结构

在这里我们先谈硬件部分:

        首先,底层硬件是计算机系统的最底层部分,包括处理器、内存、硬盘、显卡等物理设备。这些硬件是计算机系统的基础,提供了运行程序和存储数据的能力。
        其次,驱动程序是介于底层硬件和操作系统之间的软件。由于不同的硬件厂商生产的硬件设备可能采用不同的技术和协议,因此操作系统无法直接识别和管理这些硬件。驱动程序的作用就是为操作系统提供与硬件设备进行通信和控制的能力。驱动程序包含有关硬件设备的信息,可以让操作系统识别和管理硬件,并与其进行交互。
        最后,操作系统是运行在计算机硬件之上的系统软件,它是计算机系统的核心。操作系统负责管理和控制计算机的硬件和软件资源,提供用户界面,支持多任务处理和文件系统等功能。操作系统通过与驱动程序进行交互,实现对底层硬件的管理和控制。

        底层硬件提供了计算机系统的物质基础,驱动程序为操作系统提供了与硬件进行交互和控制的能力,而操作系统则负责管理和控制整个计算机系统的资源和运行(先描述,在组织)。

为什么要有操作系统?
1. 管理硬件资源:操作系统负责管理计算机的各种硬件资源,如内存、处理器、硬盘、网络等,确保它们能够有效地被应用程序使用。
2. 提供用户接口:操作系统提供了用户与计算机之间的接口,使用户能够方便地与计算机进行交互,运行程序和管理文件。
3. 调度任务:操作系统负责对计算机上运行的各个任务进行调度和管理,确保它们能够按照一定的规则和优先级进行执行。
4. 提供安全性:操作系统通过访问控制和权限管理等机制来保护计算机系统的安全,防止未授权的访问和恶意软件的入侵。
总的来说,操作系统是计算机系统中不可或缺的部分,它为应用程序的运行和用户的操作提供了基础支持和保障,对下管理号软硬件系统(手段),对上提供一个良好的运行环境(目的)。

系统调用和库函数概念

  • 在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
  • 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发。
     

3.进程 

承上启下

那在还没有学习进程之前,就问大家,操作系统是怎么管理进行进程管理的呢?很简单,先把进程描述起来,再把、进程组织起来!


3.1基本概念 

首先在操作系统中是不是只能运行一个程序呢?当然不是。

事实:

1.我们可以启动多个程序---我们一定要将多个.exe加载到内存

2.操作系统要不要管理多个加载到内存的程序呢?要的

3.操作系统如何管理加载到内存的程序 呢?先描述,再组织!

操作系统管理加载到内存的程序通常遵循以下步骤:

  • 加载程序:当用户启动一个程序时,操作系统首先会将程序的可执行文件从磁盘加载到内存中。这个过程涉及将程序的代码段、数据段和堆栈段等部分加载到内存的不同区域。
  • 设置程序的执行环境:操作系统会为每个加载到内存的程序设置一个独立的执行环境,包括分配内存空间、建立程序的数据结构、初始化寄存器等。
  •  创建进程控制块(PCB):操作系统会为每个加载到内存的程序创建一个进程控制块(PCB)是操作系统中用于管理进程的数据结构,它包含了进程的各种信息和状态,PCB对象会根据自己所包含的信息在内存中找到自己对应的程序记录和管理程序的运行状态、资源占用情况、优先级等信息,在内存中的PCB对象会形成数据结构方便操作系统的管理(增删查改)
  • 分配资源:操作系统会根据程序的需求分配各种资源,如内存空间、CPU时间片、文件句柄等,以确保程序能够正常运行。
  • 运行程序:一旦程序被加载到内存并设置好执行环境,操作系统会按照调度算法将程序放入就绪队列,等待CPU执行。当程序获得CPU时间片时,操作系统会将控制权交给程序,程序开始执行。

为什么加载到内存加载到内存,变成进程之后,我们要给每一个进行形成一个PCB对象呢?因为操作系统要进行管理

通以上的操作其实就将对进程的管理,转化成为了对PCB对象的管理,变成了操作系统对PCB对象所形成的数据结构的增删查改。

在这里我们就可以对进程下定义了:

进程= 内核PCB对象(内核数据结构)+可执行程序


 3.2Linux中的PCB

PCB:是操作系统学科的叫法。在Linux中,PCB就是task struct。

我们来见一见Linux中的task struct。这是Linux内核的源代码,里面确实存在这个结构体

task struct中有哪些属性?

命令ps axj可以查看当前的进程

我们生成了一个mytest的可执行程序,并运行它,这时候就变成了进程,程序运行结束进程也就结束了(进程是有“生命”的)。

下面是它所对应的进程,我们发现在mytest进程下面还有一个grep的进程,这是为什么?

这是因为几乎所有的指令,都是程序,运行起来也要变成进程,grep当然也不例外。


  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。

在上图中,PID一栏就是标识符,下面在程序中可以通过getpid函数查看PID

除了PID外还有PPID(父进程),在Linux中每个人进程都有一个父进程,而父进程可能有多个子进程。每一次启动进程PID几乎都会变化,因为我的进程是一个新的进程!而父进程不会变,子进程有父进程创建

我们可以查询16986这个进程,发现它就是bash(命令行解释器)。

除了ps ajx查看进程的方式,我们还可以通过proc文件去查看正在运行的程序的信息

cwd表示当前的进程的工作目录:我们在学习C语言的时候,会学习创建文件,如果你没有指定完整的路径,那么这些操作就会在这个工作目录下进行。

exe记录的是进程可执行文件的位置

  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器(pc指针): 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
  • I/ O状态信息: 包括显示的I/O请求,分配给进程的I/ O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息
     

 3.3通过系统调用创建子进程-fork初识

fork:创建一个子进程

我们先来看一段代码:

我们发现after打印了两次,一旦fork后会创建子进程,这时就会有两个执行分支了,两分支都要执行printf。我们还发现最后一个after,他的父进程就是上一个after,而上面两个的父进程是24662(bash)fork之后,后续的代码父和子都会执行

再看一段代码:

我们发现,fork是有返回值的;在父进程中fork会返回子进程的ID,因为父进程需要记住创建的子进程。在子进程中,会返回0/-1,返回0就代表fork函数执行成功,返回0来标识子进程,返回-1就代表fork函数出错了


为什么要创建子进程?

当然是要子进程帮父进程去办事,让父子做不同的事情。

看下面的代码:使用if语句进行分流,让父子做不同的事情。

通过返回值的不同来区分父子进程,进而让父子进程去做不同的事情。


fork的原理:

1.每一个进程=内核数据结构+可执行代码和数据

2.创建一个进程的时候,系统中会多一个进程;因此会给子进程创建一个task_struct,但是子进程没有代码和数据进行执行,这时子进程会默认指向父进程的代码和数据。

3.但这样是不行的,这时我们虽然是共享了代码,但要使得这个操作有意义,我们得执行不同的操作,因此fork函数就通过返回值的不同,让父与子去执行代码块不同的部分。当然这代码依旧是来自父亲,fork之后,儿子就帮父亲分担了一部分工作。

4.子进程为什么能去调度代码,是因为子进程会继承父进程中task_struct的大多数属性,以父进程为模板创建子进程。


进一步了解fork的返回值

1.给父进程返回父进程的pid,给子进程返回0,为什么?

父:子 = 1:n,父亲可以有很多儿子,而儿子只有一个父亲,因此子进程需要返回自己的ID给父亲,方便父亲唯一性的确认和控制这个子进程,而父亲是唯一的,不需要进行标识。

2.fork 函数为什么会返回两次?

调用fork只能是父进程去调用fork。如果一个函数,已经运行到了最后开始执行return的时候,这个函数的核心逻辑做完了吗?当然做完了。fork是函数,fork执行完了也需要return。而fork也是有自己的执行代码的,在return之前子进程就已经被创建了,创建好了之后,父子进程代码共享,return也是代码,那么子进程当然也可以执行return,因此fork会返回两次,一次是父进程返回的,另一次当然是子进程返回的。

3.这里还有一个最让人不能理解的地方,同一个变量id,怎么可能既等于0,又大于0 呢?

一个进程崩溃了,会不会影响其它进程?当然是不会的。

进程之间是具有独立性的,互不影响。

这个返回值也被存储在一个名为id的变量中,但这个变量是子进程的局部变量,与父进程中的id变量是完全独立的。
这两个返回值是通过操作系统内核的调度机制实现的,它确保了父进程和子进程在逻辑上是并发的,但实际上它们在物理上可能是交替执行的。由于这两个进程有独立的地址空间,因此它们各自的局部变量(即使变量名相同)也是相互独立的。
这就是为什么你会看到id变量似乎“同时”存入了两个值,但实际上这两个值分别属于两个不同的进程上下文。每个进程都有自己的变量副本,这些变量在进程内部是唯一的,并且互不干扰。


demo代码(一次创建多个子进程)

代码:

#include <stdlib.h>const int num = 10;
void worker()
{int cnt = 12;while (cnt){printf("child %d is running,cnt:%d\n", getpid(), cnt);cnt--;sleep(1);}
}
int main()
{for (int i = 0; i < num; i++){pid_t id = fork();if (id < 0) break;if (id == 0){//子进程worker();exit(0);//让子进程退出                           }printf("father create child process success,child pid:%d\n", id);}//只有父亲进程会执行到这里sleep(15);return 0;
}

在主函数 main 中,通过循环创建了10个子进程,每个子进程通过调用 worker 函数来输出信息,然后退出。父进程在创建子进程后会打印子进程的PID,并在所有子进程创建完成后通过 sleep(15) 来延迟一段时间。需要注意的是,父进程在创建子进程时应该检查 fork() 的返回值以处理可能的错误情况。

我们发现最后子进程都退出了,有<defunct>的标识,留下来的只有父进程

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

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

相关文章

Mora: Enabling Generalist Video Generation via A Multi-Agent Framework

Mora: Enabling Generalist Video Generation via A Multi-Agent Framework PDF: https://arxiv.org/html/2403.13248v1 1 概述 为弥补Sora不开源的缺陷&#xff0c;本文提出多代理框架Mora&#xff0c;整合先进视觉AI代理&#xff0c;复制Sora的全能视频生成能力。Mora能利用…

2024年《期刊引证报告》解读,迎来哪些新调整?

​ 【SciencePub学术】 近日&#xff0c;科睿唯安官方发布了一则关于2024年《期刊引证报告》&#xff1a;为增强透明度和包容性&#xff0c;期刊影响因子学科排名迎来新调整的文章。文章中对今年新调整过的地方做出了详细的解释。 截图来源&#xff1a;科睿唯安公众号 动态一…

#Linux(连接档概念)

&#xff08;一&#xff09;发行版&#xff1a;Ubuntu16.04.7 &#xff08;二&#xff09;记录&#xff1a; &#xff08;1&#xff09;硬链接&#xff08;inode&#xff0c;建立硬链接的文件inode号相同&#xff09; &#xff08;2&#xff09;创建硬链接:ln 文件名1 文件名…

css设置div的2个span一个在最左边,一个在最右边

界面&#xff1a; 代码&#xff1a; <html><style>.top span {display: block;position: absolute;margin: 0 20px; /* 添加边距以避免太靠近边缘 */ }.top span:nth-child(1) {left: 5px; /* 调整左侧位置 */ }.top span:nth-child(2) {right: 5px; /* 调整右侧位…

【前端性能】前端性能优化方法总结

关于前端性能指标和测量方法可以看这篇&#xff1a;【前端性能】前端性能指标和测量方法总结 文章目录 前端性能优化网络方向HTTP缓存本地储存HTTP升级DNS预解析使用CDN 渲染方向HTMLCSSJS图片Webpack优化 前端性能优化 可以从网络请求方向和页面渲染方向进行优化&#xff1a…

鸿蒙一次开发,多端部署(六)自适应布局

针对常见的开发场景&#xff0c;方舟开发框架提炼了七种自适应布局能力&#xff0c;这些布局可以独立使用&#xff0c;也可多种布局叠加使用。 下面我们依次介绍这几种自适应布局能力。 拉伸能力 拉伸能力是指容器组件尺寸发生变化时&#xff0c;增加或减小的空间全部分配给容…

鸿蒙一次开发,多端部署(十一)设置应用页面

本小节以“设置”应用页面为例&#xff0c;介绍如何使用自适应布局能力和响应式布局能力适配不同尺寸窗口。 页面设计 为充分利用屏幕尺寸优势&#xff0c;应用常常有在小屏设备上单栏显示&#xff0c;大屏设备上左右分两栏显示的设计&#xff0c;设置应用页面设计如下。 观察…

不要取和所用方法名字相同的类

package 练习; import java.util.*; public class StringBuilder {public static void main(String[] args){Scanner scan new Scanner(System.in);String r scan.nextLine();StringBuilder x new StringBuilder(r);System.out.println(x);}} 奉上错误代码&#xff08;上面&…

qt5-入门-标签页部件QTabWidget-1

参考&#xff1a; C GUI Programming with Qt 4, Second Edition 本地环境&#xff1a; win10专业版&#xff0c;64位&#xff0c;Qt5.12 目录 效果实现Qt Designer操作代码addStretch()解释 效果 首页有三个按钮和最近文件列表。 拖动窗口&#xff0c;按钮和文件列表仍然处…

【C++】1600. 请假时间计算

问题&#xff1a;1600. 请假时间计算 类型&#xff1a;基本运算、整数运算 题目描述&#xff1a; 假设小明的妈妈向公司请了 n 天的假&#xff0c;那么请问小明的妈妈总共请了多少小时的假&#xff0c;多少分钟的假&#xff1f;&#xff08;提示&#xff1a; 1 天有 24 小时&…

关于UDS刷写的一些杂谈

最近在做CAPL编写UDS刷写上位机的工作&#xff0c;后续过来更新现在这里查个眼&#xff0c;以免后面忘记了。 下面放一些可能会用到的知识点&#xff1a; 1.一般的刷写流程如下所示&#xff1a; 红色标记代表为功能寻址。 预编程&#xff1a;10 01&#xff0c;10 83&#xf…

Linux——du, df命令查看磁盘空间使用情况

一、实现原理&#xff1a; df 命令的全称是Disk Free &#xff0c;显而易见它是统计磁盘中空闲的空间&#xff0c;也即空闲的磁盘块数。它是通过文件系统磁盘块分配图进行计算出的。 du 命令的全称是 Disk Used &#xff0c;统计磁盘有已经使用的空间。它是直接统计各文件各目…

HarmonyOS4.0—自定义渐变导航栏开发教程

前言 今天要分享的是一个自定义渐变导航栏&#xff0c;本项目基于鸿蒙4.0。 先看效果&#xff1a; 这种导航栏在开发中也比较常见&#xff0c;特点是导航栏背景色从透明到不透明的渐变&#xff0c;以及导航栏标题和按钮颜色的变化。 系统的导航栏无法满足要求&#xff0c;我们…

8868体育助力西甲赫罗纳 争冠黑马惨遭掀翻

西甲的赫罗纳足球俱乐部是8868体育助力的球队之一&#xff0c;西甲排名第12的赫塔费队迎来了西甲第29轮的较量&#xff0c;赫塔费队此役坐镇自己的主场PK赛前排名第2的争冠超级黑马赫罗纳队。 赛前赫塔费队已经连续4轮联赛不胜&#xff08;2平2负状态低迷&#xff09;&#xff…

力扣 字符串解码

维护一个放数字的栈&#xff0c;一个放字母的栈 遇到[把数字和字母入栈&#xff0c;遇到]把当前字母循环加上数字栈头遍的字母栈头 class Solution { public:string decodeString(string s) {string ans"";stack<int>sz;stack<string>zm;里面是string …

一文讲清!进销存管理系统如何实现锁库及库存冻结?计算月加权平均成本?

进销存管理系统中的锁库及库存冻结如何实现&#xff1f;进销存管理系统如何计算月加权平均成本&#xff1f;进销存管理系统又该如何统计和预测采购需求&#xff1f;这些进销存管理难题困扰着许多企业管理者。本文将结合数年从业经验&#xff0c;深入探讨这些进销存管理难题&…

面试算法-83-不同路径 II

题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上角到…

saas架构使用实现

saas架构使用实现 saas是什么 多租户架构——是指在同一个系统中&#xff0c;为不同的客户提供不同的部署环境&#xff0c;各个客户之间的数据和操作是相互独立的。这种架构可以大幅降低系统的开发和运维成本&#xff0c;同时也能提高系统的可扩展性和灵活性。每个用户有自己特…

苹果电脑不能删除移动硬盘文件 苹果电脑移动硬盘只读模式如何更改 移动硬盘文件或目录损坏且无法读取怎么办

当我们将移动硬盘插入苹果电脑后&#xff0c;发现无法对移动硬盘中的文件进行编辑该怎么办&#xff1f;相信有不少网友遇到过这类情况。苹果电脑不能删除移动硬盘文件&#xff0c;或无法拷贝硬盘里的文件。今天我为大家解决苹果电脑移动硬盘只读模式如何更改的问题&#xff0c;…

superset 二开增加 flink 数据源连接通过flink sql 查询数据

前言 superset 目前还不支持 flink 的数据源连接&#xff0c;目前我们公司在探索使用数据湖那一套东西&#xff1a; 使用 flink 作为计算引擎使用 paimon oss对象存储对接 flink 作为底层存储使用 superset 通过 flink gateway 查询 paimon 数据形成报表 增加flink数据源 …