【Linux】操作系统与进程概念

一、操作系统

1.1概念

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

1.内核(进程管理,内存管理,文件管理,驱动管理)

2.其他程序(例如函数库,shell程序等等)

功能:操作系统将软硬件资源管理好(手段),给用户提供良好的(稳定、高效、安全、易用)使用环境(目的)。

为了更好的学习操作系统的知识,我们先认识以下概念:

计算机层次结构:

 我们先从下往上介绍学习(下三层):

1. 底层硬件:底层硬件是指计算机系统中的实际物理设备,包括内存、硬盘、显示器、键盘、鼠标等。底层硬件是计算机系统的基础,提供计算和存储能力,以及与外部世界的交互接口。

2. 驱动程序:驱动程序是一种特殊的软件,用于与特定硬件设备进行通信和控制。不同类型的硬件设备需要相应的驱动程序来进行管理和操作,例如打印机驱动程序、显卡驱动程序等。(通过与硬件设备的寄存器和接口进行交互,实现对硬件的控制和管理)

【注意】

  1. 每一个硬件都需要有与之匹配的驱动程序存在(内存和CPU不需要)
  2. 驱动程序大部分是操作系统自带的

3.操作系统:操作系统是计算机系统的核心软件,负责管理和控制计算机的硬件资源和软件资源。它提供了抽象的接口,使得应用程序可以方便地与硬件进行交互。操作系统包含一系列算法和机制,并暴露一些接口给上层用户,使上层用户能够与底层硬件进行交互,也包括对驱动程序接口的封装

【操作系统】

       操作系统本身不会直接与硬件进行交互,而是通过驱动程序来获取和管理底层硬件的数据。

        取得硬件的数据猴,为了有效管理这些不同的数据(包括软件数据硬件数据),操作系统需要先对其进行描述和组织。具体来说,操作系统通过使用 struct 结构体来描述各种硬件的信息(例如,Linux 操作系统使用 C 语言编写)。

        操作系统将每种数据采集上来后填充到相应的结构体中。随后,操作系统会对所有设备形成不同的数据结构,从而使设备的管理变成对数据结构对象的增删查改操作。

        因此,操作系统内部会存在大量的数据对象和数据结构。一个设备被操作系统管理的含义是:操作系统内存在用于管理该设备数据结构的对象。

总结:操作系统、驱动程序和底层硬件之间形成了层次化的关系。操作系统作为核心软件,管理和控制硬件资源,其依赖驱动程序与底层硬件进行通信和控制。驱动程序负责将操作系统的请求转化为硬件能够理解的指令和信号,并将硬件的响应传递给操作系统。

操作系统管理核心:

  • 进程管理
  • 内存管理
  • 驱动管理
  • 文件/io管理(外设)

上三层:

系统调用接口,库函数,用户

  • 系统调用接口:当操作系统通过驱动层维护好硬件数据和软件数据,但操作系统并不完全信任用户,所以操作系统只提供一系列的系统调用接口来供用户对操作系统进行操作。也就是说操作系统不会将全部数据的管理都暴露给用户,用户只能通过系统调用接口来控制操作。因为即便是开发者,也不能直接与操作系统进行交互(尽管从技术方面可以实现),(群众里面有坏人)。操作系统不相信我们,但同时也不得不给我们提供服务
  • 用户操作接口:这一层就对应着我们经常使用的C库或者STL库等标准库,在这一层不同的标准库将对系统调用做进一步封装,从而简化用户的操作(也就是使我们写代码更加简单,体验好),其底层依然是对系统调用接口的调用完成的工作。例如printf()函数打印在硬件上,不是直接调用硬件打印的,而是通过一些系统调用接口实现的,贯穿了整个操作系统的层次结构
  • 用户:广义上用户是使用计算机的所有人,狭义上是指开发者。

总结:

  • 一般一个用户想访问非常底层OS数据或者访问硬件,必须贯穿整个层状结构!
  • 贯穿整个层状结构,就注定用户必定要调用系统调用!
  • 在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
  • 系统调用,使用起来比较麻烦,站在用系统的人(普通人)来看,系统必须提供一些更易用的程序,于是就有了外壳程序(shell,图形化界面)。外壳程序是用C/C++语言写的,一定会调用系统调用!
  • 站在开发的人的角度,可以直接调用系统接口,但是系统调用在使用上,功能比较基础,对用户的要求相对也比较高,为了更方便的使用,人们将部分系统调用封装成为各种各样好用的函数,打包形成 库!,从此所有的开发者、用很多功能不用自己去写了,而是直接调用库函数即可!(库由专门的人来做,专业的人做专业的事情,提高开发效率降低开发成本)

二、进程 

2.1概念

        程序的一个执行实例,正在执行的程序等。它包含了程序的执行状态、内存使用情况、打开文件等信息。在内核的角度:进程是指分配系统资源(CPU时间,内存)的实体单位。

程序VS进程

        程序是一组指令或代码的集合,用于实现某种特定的计算功能,存放在硬盘。程序本身并不会占用计算机的内存资源或执行任何操作,只有在被操作系统加载到内存中并被执行时,才会成为运行中的进程。
        进程是正在执行的程序的实例。进程包含了程序的执行环境、状态信息、系统资源等,可以独立地运行、调度和控制。每个进程都有自己的内存空间、寄存器、栈、堆栈等,可以相互独立并且可以并发地执行。

2.2 进程的构成 

        操作系统在运行中会存在很多的“进程”,操作系统管理所有的"进程",需要先对进程描述,再用数据结构进行组织!操作系统是用C语言写的,操作系统内用struct结构体描述进程信息  这个记录进程信息的结构体,叫做进程控制块(PCB)记录如:进程状态、程序计数器、寄存器内容等数据然后操作系统对进程的管理就变成了对PCB的管理。和进程的可执行程序没有关系。

在Linux中描述进程的结构体叫做task_struct。

Linux下的PCB大概样子:(简易)     

struct task_struct {pid_t pid;                         // 进程IDlong state;                        // 进程状态unsigned int flags;                // 进程标志struct mm_struct *mm;              // 进程的内存管理信息struct task_struct *parent;        // 父进程struct list_head children;         // 子进程列表struct files_struct *files;        // 进程打开的文件信息struct fs_struct *fs;              // 文件系统信息// 其他字段...
};

解释:PCB中通常会记录的重要信息

  • 进程标识符(PID):每个进程都有一个唯一的标识符,用于区分不同的进程。

  • 进程状态:表示进程当前的状态,例如运行态、就绪态、阻塞态等。

  • 程序计数器:保存进程正在执行的下一条指令的地址。

  • 寄存器内容:包括通用寄存器、堆栈指针、程序状态字(PSW)等。

  • 内存管理信息:例如基址寄存器、限长寄存器、页表或段表等,描述进程使用的内存区域。

  • 文件描述符:记录进程打开的文件列表及其相关信息。

  • 进程优先级:表示进程的优先级,用于调度算法中决定进程的执行顺序。

  • 账户信息:记录与进程相关的用户信息,例如用户ID、组ID等。

  • I/O状态信息:描述进程使用的I/O设备及其状态。

  • 进程间通信信息:记录进程间的通信机制和相关的数据结构。

注:可以看到PCB有很多指针类型,说明PCB并不直接存储数据而是记录进程各种数据的地址。可以说进程的构成是由 PCB进程的实际数据共同组成

 综上:进程的构成可以看作:PCB+进程的数据。

2.3 进程的相关操作

2.3.1 进程的查看

        方式1:进程的信息可以通过命令ps ajx 进程名/进程id 命令显示所有进程的详细信息。

如下:

分析:

  • PPID:父进程的进程ID,即创建当前进程的进程ID。

  • PID:当前进程的进程ID,每个进程都有一个唯一的ID。

  • PGID:进程组ID,一组进程的共同标识符。进程组用于信号和作业控制。

  • SID:会话ID,一组进程的共同标识符。会话通常包含一个控制终端和若干进程组。

  • TTY:终端设备名称,显示进程关联的终端(如tty1pts/0等)。

  • TPGID:控制终端的前台进程组ID,指示当前控制终端的前台进程组。

  • STAT:进程状态,通常用一两个字母表示。(介绍:)

  • UID:用户ID,表示创建该进程的用户。每个用户在系统中有一个唯一的ID。

  • TIME :进程所使用的总CPU时间。

  • COMMAND:启动进程的命令或程序名。


        方式2:  ls /proc/进程pid   proc是一个动态的目录结构,存放所有存在的进程,目录的名称;proc是process的简称。操作如下:

2.3.2 进程的创建

通过系统调用创建子进程——fork()

SYNOPSIS#include <sys/types.h>#include <unistd.h>pid_t fork(void);

代码演示: 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>int main() {pid_t pid;// 创建子进程pid = fork();if (pid < 0) { // 创建子进程失败fprintf(stderr, "Fork failed\n");return 1;}else if (pid == 0) { // 子进程printf("This is the child process. PID: %d\n", getpid());printf("Child's Parent PID: %d\n", getppid());}else { // 父进程printf("This is the parent process. PID: %d\n", getpid());printf("Parent's Child PID: %d\n", pid);}return 0;
}

 代码解析:在fork()之前,只有父进程在执行代码。调用fork()之后,父进程和子进程会同时执行从fork()返回的位置开始的后续代码。通过检查fork()的返回值,可以区分父进程和子进程,从而让它们执行不同的代码片段。这种机制是多进程编程的基础。

接下来我们来分析一下fork()在系统里面做了说明?

        fork创建子进程,操作系统以父进程为模板,为子进程创建PCB,但是创建出来的子进程是没有代码和数据的,要和父进程共享相同代码和部分数据!所以fork之后,父子进程会同时执行一样的代码。(fork之前的代码子进程也共享,但子进程也会继承了父进程的读写位置)子进程用父进程的代码和数据进行初始化,子进程一开始会和父进程共享一切,到有不同(包括更改变量,代码不一样)的时候才会执行写实拷贝

关于fork()有两个返回值?

        1. 找到父进程的pcb对象

        2. 为子进程创建pcb

        3. 根据父进程pcb,初始化子进程pcb

        4. 子进程的pcb指向父进程的代码和数据 让子进程放入调度队列中,和进程一样去排队

        5. return;

        注:return执行之前,fork()已完成了创建子进程,并将子进程放入调度队列中运行,return语句也是代码,所以return也要被父子进程共享,父子进程都要执行return语句

fork()两个返回值的意义?

  • 父进程返回子进程的PID

            这样,父进程可以知道新创建的子进程的进程ID。父进程可以通过这个PID对子进程进行管理,例如等待子进程结束或发送信号给子进程。
  • 子进程返回0:

    子进程返回0,这使子进程能够识别自身,并执行子进程特有的代码。子进程在返回0时,可以独立于父进程执行自己的逻辑。

2.3.3 进程终止

方法1:kill 命令,向进程发送信号,以控制其行为或终止进程。
常用选项:强制终止目标进程。 

kill -9 22756

 方法2:在代码中使用exit()函数

#include <stdlib.h>int main() {// 正常退出,返回状态码0exit(0);
}

方法3:在main()函数中,使用return语句可以终止进程并返回退出状态码。

#include <stdio.h>int main() {// 正常退出,返回状态码0return 0;
}

方法4:使用abort()函数 

#include <stdlib.h>int main() {// 立即终止进程abort();
}

【注意】:abort() 函数会立即终止进程,使程序以失败状态终止,通常返回一个非零状态码。通常abort用于程序检测到严重错误或异常情况时,需要立即终止并生成核心转储以供调试。 

 

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

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

相关文章

深度学习中的学习率调度器(scheduler)分析并作图查看各方法差异

文章目录 1. 指数衰减调度器&#xff08;Exponential Decay Scheduler&#xff09;工作原理适用场景实现示例 2. 余弦退火调度器&#xff08;Cosine Annealing Scheduler&#xff09;工作原理适用场景实现示例 3. 步长衰减调度器&#xff08;Step Decay Scheduler&#xff09;工…

WEB攻防-通用漏洞_XSS跨站_权限维持_捆绑钓鱼_浏览器漏洞

目录 XSS的分类 XSS跨站-后台植入Cookie&表单劫持 【例1】&#xff1a;利用beef或xss平台实时监控Cookie等凭据实现权限维持 【例2】&#xff1a;XSS-Flash钓鱼配合MSF捆绑上线 【例3】&#xff1a;XSS-浏览器网马配合MSF访问上线 XSS的分类 反射型&#xff08;非持久…

【AIGC-ChatGPT进阶提示词指令】智慧母婴:打造基于成长树的儿童发展引导系统

第一次进入全站综合热榜&#xff0c;有点紧张 好了&#xff0c;开始今天的内容&#xff0c;今天的内容是基于育儿的系统 今天继续回馈大家&#xff0c;最近都是可以在自媒体上使用的提示词。提示词在最下方 引言 在人工智能时代&#xff0c;如何将传统育儿智慧与现代教育理念有…

使用葡萄城+vue实现Excel

最终实现效果如下 包含增加复选框 设置公式 设置背景颜色等&#xff0c;代码实在太多 有需要可留言 第一步&#xff1a;创建表头 请使用官网提供的网址&#xff1a;在线 Excel 编辑器 | SpreadJS 在线表格编辑器 1.点击下方号&#xff0c;创建一个新的sheet页 默认新创建的she…

【Qt】01-了解QT

踏入QT的殿堂之路 前言一、创建工程文件1.1 步骤介绍1.2 编译介绍方法1、方法2、编译成功 二、了解框架2.1 main.cpp2.2 .Pro文件2.2.1 注释需要打井号。2.2.2 F1带你进入帮助模式2.2.3 build文件 2.3 构造函数 三、编写工程3.1 main代码3.2 结果展示 四、指定父对象4.1 main代…

《异步编程之美》— 全栈修仙《Java 8 CompletableFuture 对比 ES6 Promise 以及Spring @Async》

哈喽&#xff0c;大家好&#xff01;在平常开发过程中会遇到许多意想不到的坑&#xff0c;本篇文章就记录在开发过程中遇到一些常见的问题&#xff0c;看了许多博主的异步编程&#xff0c;我只能说一言难尽。本文详细的讲解了异步编程之美&#xff0c;是不可多得的好文&#xf…

unity——Preject3——面板基类

目录 1.Canvas Group Canvas Group 的功能 Canvas Group 的常见用途 如何使用 Canvas Group 2.代码 3.代码分析 类分析:BasePanel 功能 作用 实际应用 代码解析:hideCallBack?.Invoke(); 语法知识点 作用 虚函数(virtual)和抽象类(abstract)的作用与区别 …

Windows service运行Django项目

系统&#xff1a;Windows Service 软件&#xff1a;nssm&#xff0c;nginx 配置Django项目 1、把Django项目的静态文件整理到staticfiles文件夹中 注&#xff1a;settings中的设置 STATIC_URL /static/ STATIC_ROOT os.path.join(BASE_DIR, staticfiles/) STATICFILES_DI…

SQL面试题1:连续登陆问题

引言 场景介绍&#xff1a; 许多互联网平台为了提高用户的参与度和忠诚度&#xff0c;会推出各种连续登录奖励机制。例如&#xff0c;游戏平台会给连续登录的玩家发放游戏道具、金币等奖励&#xff1b;学习类 APP 会为连续登录学习的用户提供积分&#xff0c;积分可兑换课程或…

【大数据】机器学习-----线性模型

一、线性模型基本形式 线性模型旨在通过线性组合输入特征来预测输出。其一般形式为&#xff1a; 其中&#xff1a; x ( x 1 , x 2 , ⋯ , x d ) \mathbf{x}(x_1,x_2,\cdots,x_d) x(x1​,x2​,⋯,xd​) 是输入特征向量&#xff0c;包含 d d d 个特征。 w ( w 1 , w 2 , ⋯ ,…

OpenCV基础:矩阵的创建、检索与赋值

本文主要是介绍如何使用numpy进行矩阵的创建&#xff0c;以及从矩阵中读取数据&#xff0c;修改矩阵数据。 创建矩阵 import numpy as npa np.array([1,2,3]) b np.array([[1,2,3],[4,5,6]]) #print(a) #print(b)# 创建全0数组 eros矩阵 c np.zeros((8,8), np.uint8) #prin…

(蓝桥杯)二维数组前缀和典型例题——子矩阵求和

题目描述 小 A 同学有着很强的计算能力&#xff0c;张老师为了检验小 AA同学的计算能力&#xff0c;写了一个 n 行 m 列的矩阵数列。 张老师问了小 A 同学 k 个问题&#xff0c;每个问题会先告知小 A 同学 4 个数 x1,y1,x2,y2画出一个子矩阵&#xff0c;张老师请小 A同学计算出…

Node.js - HTTP

1. HTTP请求 HTTP&#xff08;Hypertext Transfer Protocol&#xff0c;超文本传输协议&#xff09;是客户端和服务器之间通信的基础协议。HTTP 请求是由客户端&#xff08;通常是浏览器、手机应用或其他网络工具&#xff09;发送给服务器的消息&#xff0c;用来请求资源或执行…

[读书日志]8051软核处理器设计实战(基于FPGA)第七篇:8051软核处理器的测试(verilog+C)

6. 8051软核处理器的验证和使用 为了充分测试8051的性能&#xff0c;我们需要测试每一条指令。在HELLO文件夹中存放了整个测试的C语言工程文件。主函数存放在指令被分为五大类&#xff0c;和上面一样。 打开后是这样的文件结构。HELLO.c是主文件&#xff0c;这是里面的代码&am…

深入浅出 Android AES 加密解密:从理论到实战

深入浅出 Android AES 加密解密&#xff1a;从理论到实战 在现代移动应用中&#xff0c;数据安全是不可忽视的一环。无论是用户隐私保护&#xff0c;还是敏感信息的存储与传输&#xff0c;加密技术都扮演着重要角色。本文将以 AES&#xff08;Advanced Encryption Standard&am…

IDEA编译器集成Maven环境以及项目的创建(2)

选择&#xff1a;“File” ---> "Othoer Setting" --> "Settings for New Projects..." --->搜索“Maven” 新建项目 利用maven命令去编译这个项目 利用maven去打包

Open FPV VTX开源之默认MAVLink设置

Open FPV VTX开源之默认MAVLink设置 1. 源由2. 准备3. 连接4. 安装5. 配置6. 测试6.1 启动wfb-ng服务6.2 启动wfb-ng监测6.3 启动QGroundControl6.4 观察测试结果 7. 总结8. 参考资料9. 补充9.1 telemetry_tx异常9.2 DEBUG串口部分乱码9.3 PixelPilot软件问题 1. 源由 飞控图传…

gesp(C++五级)(4)洛谷:B3872:[GESP202309 五级] 巧夺大奖

gesp(C五级)&#xff08;4&#xff09;洛谷&#xff1a;B3872&#xff1a;[GESP202309 五级] 巧夺大奖 题目描述 小明参加了一个巧夺大奖的游戏节目。主持人宣布了游戏规则&#xff1a; 游戏分为 n n n 个时间段&#xff0c;参加者每个时间段可以选择一个小游戏。 游戏中共有…

像JSONDecodeError: Extra data: line 2 column 1 (char 134)这样的问题怎么解决

问题介绍 今天处理返回的 JSON 的时候&#xff0c;出现了下面这样的问题&#xff1a; 处理这种问题的时候&#xff0c;首先你要看一下当前的字符串格式是啥样的&#xff0c;比如我查看后发现是下面这样的&#xff1a; 会发现这个字符串中间没有逗号&#xff0c;也就是此时的J…

道旅科技借助云消息队列 Kafka 版加速旅游大数据创新发展

作者&#xff1a;寒空、横槊、娜米、公仪 道旅科技&#xff1a;科技驱动&#xff0c;引领全球旅游分销服务 道旅科技 &#xff08;https://www.didatravel.com/home&#xff09; 成立于 2012 年&#xff0c;总部位于中国深圳&#xff0c;是一家以科技驱动的全球酒店资源批发商…