计算机操作系统之进程与线程
⭐️前面的话⭐️
本篇文章将介绍计算机操作系统的相关内容,主要内容有进程,进程调度,并行与并发的概念,进程间通信,进程与线程的区别。
📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创
📆华为云首发时间:🌴2022年6月30日🌴
✉️坚持和努力一定能换来诗与远方!
💭参考书籍:📚《计算机操作系统》,📚《深入理解计算机系统》
💬参考在线编程网站:🌐牛客网🌐力扣
博主的码云gitee,平常博主写的程序代码都在里面。
博主的github,平常博主写的程序代码都在里面。
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!
🍋1.什么是操作系统?
操作系统本质上是一个软件,配置在硬件上的第一个软件,可以管理软件和硬件,使其可以有条不紊地运行。
对于操作系统下层,操作系统需要管理好硬件,对于操作系统上层要给软件提供稳定的运行环境,所以操作系统是一个极其重要也极其复杂的“软件”。
对于我们程序员,最重要的是要知道操作系统是如何对进程进行管理,那么问题来了,进程是一个什么东东?
🍋2.进程与线程
🍒2.1进程
简单说进程就是正在运行的程序,通过双击可执行文件.exe
文件,操作系统就会把这个可执行文件加载到内存上,并在CPU上执行可执行文件中的指令,这样这个exe
就跑起来了,就是一个正在运行的程序,也称作一个进程,或者一个任务。
目前我们的电脑都是多进程模式,宏观上,可以有很多个进程同时执行,打开我们电脑的任务管理器,就能查看到我们电脑的进程。
其中有一部分进程需要我们主动的去执行应用的可执行文件,比如QQ,WPS,网易云音乐等,还有一部分是操作系统自动启动的进程。
🍒2.2线程
知道了进程就是运行的程序,那线程又是什么?线程是进程内部的一部分,如果说进程是一个工厂,那么线程就是工厂中的生产线,所以一个进程可以包括很多个线程,一个进程至少拥有一个线程。
咱们所写的java代码,最终都是通过java进程(jvm)跑起来的。
🍒2.3进程的管理
操作系统是如何对进程进行管理的呢?首先,需要描述一个线程(明确线程的一些属性,操作系统中是通过C/C++来实现的),对于Linux系统是使用结构体来描述进程的,这个结构体也被称为进程控制块(PCB),对进程进行描述后,然后就是组织线程,线程的本质上也是数据,那么对数据的组织需要通过数据结构来进行组织,在Linux系统中是通过双链表来组织线程。
所以对线程的增删查改本质上就是对双链表进行增删查改,当然这个双链表是复杂的双链表,但是对线程的操作的基本思路和操作双链表是一样的。
🍇2.3.1PCB中的一些属性
🍉进程id(pid):进程的一个“身份证号”,进行身份标识。
🍉内存指针:指明该进程的代码或指令的内存在哪个地方,以及该进程所依赖的数据在哪里。
🍉文件描述符表:程序运行中,离不开和文件打交道,进程每打开一次文件,就会在文件描述表上记录一些重要的信息,这个文件描述符表可以视为一个结构体数组,每一个结构体对应一个信息,这个文件描述符数组的下标就是文件描述符。
一个进程一运行,操作系统就会自动打开至少3个文件:标准输入(System.in),标准输出(System.out),标准错误(System.err)。
想要一个进程正常工作就需要为这个进程分配资源,包括但不限于内存,硬盘,CPU。
🍇2.3.2并行与并发
并行性和并发性是既相似又有区别的两个概念。并行性是指两个或多个事件在同一时刻发生。而并发性是指两个或多个事件在同一时间间隔内发生。
从宏观上来讲,并行与并发没有区别,或者说根本就看不出来。
从微观上来讲,并行表示两个CPU核心运行两个任务的代码,并发表示一个CPU核心先运行任务A的代码,再运行任务B的代码,然后再运行任务A的代码,再运行任务B的代码,以此类推。只要运行得足够快,就是两个任务在同时运行。
🍇2.3.3进程的调度
其实调度的最小单位不是进程,而是线程,但为了方便描述进程的调度,我们假定此处的进程只有一个线程,这样就可以将线程的调度视为进程的调度,这里我们谈到的进程调度是基于多任务操作系统,就是从宏观上看,同一时间能够同时运行多个进程。
操作系统对线程的调度可以理解为“时间管理大师”。
比如有三个进程A,B,C,不妨将操作系统比作一个完美的小姐姐,将线程A,B,C比作三位小哥哥,A特别帅,B特别有钱,C特别会舔。
这位小姐姐特别爱说话,爱交际,爱谈恋爱,但是这个世界上并没有绝对完美的小哥哥,小姐姐为了体验到“一场完美的恋爱”,同时与A, B, C 一起谈恋爱,毕竟在这位小姐姐眼中,帅+有钱+会舔的小哥哥是世界上最完美的。
要同时谈三位男朋友,那么这三位男朋友一定不能见面。所以小姐姐需要严密地安排与三位小哥哥谈恋爱的时间,确保时间不能重合,比如:
因为小姐姐特别喜欢帅的,其次是有钱的,最后是会舔的,所以小姐姐对A, B, C的安排有了优先级,给A安排的时间多一点,B次之,C最后。
这位小姐姐的一周时间安排表,堪称时间管理大师:
时间 | 安排 |
---|---|
星期一 | 与C谈恋爱 |
星期二到星期三 | 与B谈恋爱 |
星期四到星期六 | 与A谈恋爱 |
星期日 | 休息 |
像这样的一个时间安排,就是进程的调度。谈恋爱期间,如果B需要出差一个月,那么在小姐姐眼中,B这种状态就称为阻塞或睡眠状态,如果正常,男朋友可以随叫随到,则在小姐姐眼中就称这种状态为就绪状态,小姐姐正在与A谈恋爱的状态称为执行状态。
因为这位小姐姐与很多位小哥哥同时谈恋爱,总会有时候“串戏”,就比如A需要小姐姐准备礼物庆祝节日,B想要带小姐姐去夏威夷旅游,要小姐姐做好准备,但是有一天B问小姐姐准备好没?小姐姐回了一句礼物早就准备好了,这样就“串戏”了,小姐姐花了很长的精力才将B忽悠过去,经历了这件事之后,小姐姐吸取了教训,准备好一个记事本来记录与男朋友们重要的信息,这样,小姐姐从来就没有串过戏。
像上面小姐姐所用的记事本发挥的作用就是进程调度中的记账信息的作用。
🍓进程的状态: 如果进程处于随时都能被调度的状态,就称这个状态为就绪,如果进程由于一系列因素无法及时响应调度,则称这个状态为阻塞或睡眠,线程正在CPU上执行的状态称为执行状态。
🍓进程的优先级: 就是类似与上面时间管理大师所认为的优先级,比如A进程最重要,那么该进程优先级最高,执行时优先执行A进程。
🍓记账信息: 统计每个进程,分别执行了多久,分别执行了哪些指令,分别排队等待了多久时间,可以给进程调度提供指导依据。
🍓上下文: 表示上一次进程被调度出的时候,程序的执行状态,这样下一次进程调CPU时就能接着上次的状态继续运行,所以进程调度出之前,都需要先把CPU上寄存器上的数据保存到内存中,相当于存档,下次该进程再被调进CPU时,就可以根据上次储存在内存中的数据恢复到寄存器中。
进程的调度其实是操作系统对CPU资源分配,那内存资源该如何分配呢?
🍇2.3.4进程间通信
操作系统上同时运行着多个进程,我们来考虑一种情况,就是当一个进程出现bug导致进程崩溃,其他进程会不会受影响呢?对于现代的操作系统,是不会影响的。因为线程之间通过虚拟地址空间,来保证进程之间的独立性。
每个进程只能访问自己的那一块虚拟地址空间的数据,无法访问其他进程虚拟地址空间的数据,这样当一个进程崩溃时,另外的进程不会受到影响,这样就将各个进程隔离起来了。
但是,在实际工作开发中,进程间常常需要进行交互,为了实现进程间的通信,操作系统提供了一块“公共空间”,进程A可以先把数据存入“公共空间”,然后进程B可以到“公共空间”取出数据,这样就实现了进程间的通信。
操作系统提供的“公共空间”有很多种,有储存大的也有小的,有访问速度快的也有慢的,现在最常见的进程间通信机制有:
- 文件操作。
- 网络操作(socket)。
那么为什么要引出进程这样一个概念呢?因为现代的操作系统都是多任务操作系统,为了最大效率地运行程序,我们需要进行并发编程,毕竟一群人完成任务的速度比一个人要快的多。
🍇2.3.5并发编程
通过多进程是完全可以实现并发编程的,但是存在一些小问题,问题根源在于进程的创建需要分配资源,进程的销毁需要回收资源,而分配和回收资源的效率相对来说是比较低的,成本是比较高的。
打个比方,你从网上组装了一台电脑,收到货后发现电脑有点小问题,和商家商量后,最终决定退货,退完货后,老板需要将零件拆开,放回到原位,这个过程需要花费的时间和精力成本是比较高的,而资源的分配与回收也是如此。
🍓那么如何解决这个问题呢?
方案A: 使用进程池,与字符串常量池类似,将已经创建的进程存入常量池,后面需要使用时直接加载即可,但是也存在问题,那就是闲置的进程也会占用资源,相当于空间换时间,消耗空间来提升效率。
方案B: 使用多线程来实现并发编程,因为进程包含线程,一个进程中包含多个线程,所以线程比进程轻量,因此Linux中也将线程称为轻量级进程(LWP),正是因为线程比进程轻量的多,线程的创建与销毁的成本很低,因此使用多线程实现并发编程比多进程更加合适。
打个小比方,进程相当于一个工厂,线程相当于工厂中的生产线,比如有一个任务需要生产1万台手机,有两个方案:
- 建造两个工厂进行生产。
- 建造一个工厂,多增加一批生产线。
上面两种方案都以相同的效率生产手机,但是方案1需要多建造一个工厂,方案2只需要增加一批生产线,很明显方案1付出的代价大的多,而方案1表示多进程实现并发编程,方案2表示多线程实现并发编程。
🍇2.3.6进程与线程的区别(面试高频)
🍓进程与线程的区别(面试高频题):
- [x] 进程包含线程,一个进程可以只有一个线程,也可以拥有多个线程。
- [x] 进程间是独立的,每个进程都有独立的虚拟地址空间,一个进程崩溃不会影响其余的进程,但是在同一个进程中,多个线程是共用一块资源,一个线程崩溃,这个进程中的所有线程都会崩溃。
- [x] 进程是操作系统分配资源的基本单位,线程是操作系统调度执行的基本单位。
- 点赞
- 收藏
- 关注作者
评论(0)