理解Linux中进程的概念

简介: 理解Linux中进程的概念

冯诺依曼体系

0bddaf5122bdf528d5f10d09fd9031d3.png

上图中的存储器指的是内存,内存的速度是较快的

内存是掉电易失的并不能永久存储数据。磁盘属于外存拥有永久性存储能力,是外设的一种,磁盘即是输出设备也是输入设备(外设是相对于内存和CPU而定义的,可以分为输入/输出设备,外设的速度较慢)

运算器 + 控制器 + 其他 = CPU,CPU的速度是极快的

CPU运算时是需要数据的,它只能被动的接受运算指令和数据。编译的本质就是把程序翻译成CPU认识的指令让CPU能够去运行。

CPU会在控制信号层面和外设会有交互

因为外设比内存的速度慢很多,所以CPU再读取和写入的时候,在数据层面只和内存交互。因为数据是存储在磁盘上的,所以内存在和CPU交互前,磁盘会预先的把数据写入到内存里等待CPU需要,因此程序要运行必须先加载到内存,所以内存也可以看成是一个大的缓存。而这种内存和外设的数据交互就是I/O操作

操作系统(OS)

操作系统是一个进行软硬件资源管理的软件。操作系统要通过合理的管理软硬件资源,为用户提供良好的、稳定的、高效的、安全的执行环境。操作系统不需要直接和硬件交互,只需要通过驱动拿到硬件的数据进行管理

操作系统会对数据先描述(定义一个结构,每个数据都是一个结构体对象),再组织(将所有的结构体对象用链表结构链起来)

操作系统为了确保自身安全,并不能让用户直接访问。用户可以通过发送指令,用户操作接口(shell,lib)接受指令再去调用操作系统接口,操作系统接收后再执行对应内容34f0bda3c879bfef0a22f2cfbb5fffc0.png

进程/PCB概念

程序的本质就是文件,在磁盘上存储

由于内存会从硬盘上加载很多的程序进来,所以操作系统要对这些程序管理起来,首先会把每个进程描述成一个结构体 (struct task_struct),里面保存了该进程的所有属性和该进程对应的代码和属性地址以及下一个结构体的地址。每一个结构体就可以称为每个程序的PCB(进程控制块)

进程 = 加载进内存的程序 + 该程序对应的PCB

CPU执行就会去找优先级高的PCB,通过PCB找到对应的代码并执行。如果某个进程结束或者死亡了,CPU就会释放掉该进程对应的PCB和可执行程序。进程在调度运行的时候,是具有动态属性的



4e3c0afa6b7b7d48b65619d7c0732482.png

进程常用的调用操作

PPID为父进程ID,PID为当前进程ID(子进程)

ps ajx – 显示当前所有进程

ps ajx | grep “进程名” – 查看指定进程

ls /proc/ – 查看所有进程(以文件形式,每个进程都是一个文件)

进入进程文件后可以查看该进程的所有属性。当进程运行时删掉硬盘中的可执行文件时,进程还是会运行

kill -9 PID – 杀掉指定进程

getpid() – 返回当前进程的ID – <sys/types.h>

getppid() – 返回当前进程的父进程ID – <sys/types.h>

fork() – 创建子进程 – <unistd.h>

fork()执行前只有一个父进程,执行后:父进程+子进程。创建成功后子进程ID会返回给父进程,0返回给子进程

56e5bc5143bcdf42f584f7f04604abfa.png


一个程序可以有多个进程同时运行相同的代码,也就是说父进程和子进程可以共享执行fork()之后的代码,通过返回值不同可以控制多个进程执行不同的代码–多进程–并发

进程状态

不同的操作系统可能状态的名称不一样或者也会有不一样的状态,常见的状态有运行,阻塞,挂起,新建,就绪,等待,挂机,死亡……

一个进程的状态也是进程内部的属性,在PCB里放着

进程的这么多状态都是为了满足不同的场景

进程不只是会等待(占用)CPU资源,也会占用外设资源。每一个外设资源都会有自己的等待队列

进程的状态本质上是进程在不同的队列里,等待某种资源

一个CPU有一个运行队列,让进程入队列本质上是将该进程的PCB结构体放入运行队列中。

运行状态:

凡是PCB在运行队列里的进程都是运行状态,并不是正在运行时才是运行状态

阻塞状态:

进程不能直接被CPU调用,并不在运行队列中,而是将进程的PCB对象放到硬件的等待队列里

挂起状态:

因为内存的空间有限,如果有大量的进程处于阻塞状态的话就会大量的占用内存的空间,所以操作系统为了避免这种情况就会将阻塞的进程对应的代码和数据备份一份到硬盘并删除掉在内存中的那一份,但是此时进程并没有被释放掉,它的PCB还是留在内存中,这时候的进程就处于挂起状态。(阻塞不一定挂起但是挂起一定是阻塞)

对于Linux来讲:运行状态–R、睡眠状态–S,暂停状态–T,深度睡眠状态–D,追踪暂停状态–t,僵尸状态–Z

运行状态–R

当进程的PCB处于运行队列中时就是运行状态

7b2c81044fa241db4b088555ae570076.png

睡眠状态–S

因为CPU的运行速度非常快,所以一般来说只要访问到外设进程大部分时间都是在等待的也就是阻塞状态,Linux上的睡眠状态就是阻塞状态的一种

暂停状态–T

kill -19可以让进程变为暂停状态,也是阻塞的一种。kill -18可以恢复状态。恢复后的进程会变为后台运行

深度睡眠–D

如果当前的进程太多了,挂起也解决不了内存空间饱满的时候,操作系统就会自动的杀掉某一些进程,但是这里就会出现一些问题。因为操作系统杀死进程是不会根据用户意愿的,所以难免就会杀死一些比较重要的进程,当进程被杀死后就不可以恢复了。

为了应对这种情况,Linux就设定了深度睡眠状态,处于深度睡眠状态的进程,是不可以被用户和操作系统杀掉的,只能通过自己醒来或者断电的操作才可以杀掉

深度睡眠一般只会出现在高IO的情况下

追踪暂停状态–t

追踪暂停状态是一种特殊的暂停状态,进程处于此状态表示该进程正在被追踪,比如调试进程时

僵尸状态–Z

一般来说进程退出的时候,不能立即释放其对应的资源,需要保存一段时间让父进程或者操作系统读取到它的资源。当进程退出时到父进程读取前的这段时间里,进程就属于是僵尸状态。如果不回收僵尸状态的子进程会导致内存泄漏

当状态后面有个+号时代表前台运行,此时命令行不能写入数据。没有+号时是后台运行,此时可以在命令行写入指令并响应,但是此时不能用ctrl+c终止进程,只能用kill -9直接杀死

孤儿进程是指父进程提前退出后,为了防止子进程无法管理回收资源,这时子进程会被操作系统(1号进程)领养,被操作系统领养的进程就被称为孤儿进程。

进程优先级

CPU资源分配的先后顺序就是指进程的优先级。在Linux中优先级的本质就是PCB里面的一个属性(可能是一个整数,可能是几个整数)

Linux的最终优先级 = 老的优先级(PRI默认为80)+ NI值。修改优先级就是修改NI值

最终优先级的范围是[60,99],所以NI值的修改范围在[-20,19]

修改优先级的步骤:

top指令(可能需要sudo提高权限)------输入r-------输入需要修改的进程id--------输入想要修改的NI值

进程的其他概念

竞争性:

系统进程数目众多,而CPU资源只有少量甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务更合理竞争相关资源,便具有了优先级

独立性:

多进程运行需要独享各种资源,多进程运行期间互不干扰

并行:

多个进程在多个CPU下分别同时进行运行,这称之为并行

并发:

多个进程在一个CPU下采用进程切换的方式,在一段时间之内让多个进程都得以推进,称之为并发

进程的切换:

CPU不会等待一个进程执行完再执行下一个进程,而是每个进程都会有自己的时间片,当进程执行的时间到了后,CPU就会切换进程执行。

CPU会有一套寄存器,寄存器是被所有进程共享的,但是寄存器里的数据只属于当前进程。进程切换的时候,需要先进行上下文保护,这里的上下文指的是CPU里的寄存器的数据,而不是寄存器。当进程恢复运行时,上下文需要恢复


目录
相关文章
|
并行计算 Linux
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
394 67
|
11月前
|
NoSQL Linux 编译器
GDB符号表概念和在Linux下获取符号表的方法
通过掌握这些关于GDB符号表的知识,你可以更好地管理和理解你的程序,希望这些知识可以帮助你更有效地进行调试工作。
465 16
|
11月前
|
Web App开发 Linux 程序员
获取和理解Linux进程以及其PID的基础知识。
总的来说,理解Linux进程及其PID需要我们明白,进程就如同汽车,负责执行任务,而PID则是独特的车牌号,为我们提供了管理的便利。知道这个,我们就可以更好地理解和操作Linux系统,甚至通过对进程的有效管理,让系统运行得更加顺畅。
305 16
|
11月前
|
Unix Linux
对于Linux的进程概念以及进程状态的理解和解析
现在,我们已经了解了Linux进程的基础知识和进程状态的理解了。这就像我们理解了城市中行人的行走和行为模式!希望这个形象的例子能帮助我们更好地理解这个重要的概念,并在实际应用中发挥作用。
213 20
|
10月前
|
监控 Shell Linux
Linux进程控制(详细讲解)
进程等待是系统通过调用特定的接口(如waitwaitpid)来实现的。来进行对子进程状态检测与回收的功能。
229 0
|
10月前
|
存储 负载均衡 算法
Linux2.6内核进程调度队列
本篇文章是Linux进程系列中的最后一篇文章,本来是想放在上一篇文章的结尾的,但是想了想还是单独写一篇文章吧,虽然说这部分内容是比较难的,所有一般来说是简单的提及带过的,但是为了让大家对进程有更深的理解与认识,还是看了一些别人的文章,然后学习了学习,然后对此做了总结,尽可能详细的介绍明白。最后推荐一篇文章Linux的进程优先级 NI 和 PR - 简书。
298 0
|
10月前
|
存储 Linux Shell
Linux进程概念-详细版(二)
在Linux进程概念-详细版(一)中我们解释了什么是进程,以及进程的各种状态,已经对进程有了一定的认识,那么这篇文章将会继续补全上篇文章剩余没有说到的,进程优先级,环境变量,程序地址空间,进程地址空间,以及调度队列。
178 0
|
10月前
|
Linux 调度 C语言
Linux进程概念-详细版(一)
子进程与父进程代码共享,其子进程直接用父进程的代码,其自己本身无代码,所以子进程无法改动代码,平时所说的修改是修改的数据。为什么要创建子进程:为了让其父子进程执行不同的代码块。子进程的数据相对于父进程是会进行写时拷贝(COW)。
240 0
|
存储 Linux 调度
【Linux】进程概念和进程状态
本文详细介绍了Linux系统中进程的核心概念与管理机制。从进程的定义出发,阐述了其作为操作系统资源管理的基本单位的重要性,并深入解析了task_struct结构体的内容及其在进程管理中的作用。同时,文章讲解了进程的基本操作(如获取PID、查看进程信息等)、父进程与子进程的关系(重点分析fork函数)、以及进程的三种主要状态(运行、阻塞、挂起)。此外,还探讨了Linux特有的进程状态表示和孤儿进程的处理方式。通过学习这些内容,读者可以更好地理解Linux进程的运行原理并优化系统性能。
470 4
|
Linux 数据库 Perl
【YashanDB 知识库】如何避免 yasdb 进程被 Linux OOM Killer 杀掉
本文来自YashanDB官网,探讨Linux系统中OOM Killer对数据库服务器的影响及解决方法。当内存接近耗尽时,OOM Killer会杀死占用最多内存的进程,这可能导致数据库主进程被误杀。为避免此问题,可采取两种方法:一是在OS层面关闭OOM Killer,通过修改`/etc/sysctl.conf`文件并重启生效;二是豁免数据库进程,由数据库实例用户借助`sudo`权限调整`oom_score_adj`值。这些措施有助于保护数据库进程免受系统内存管理机制的影响。

热门文章

最新文章