引言
大家好,我是青花瓷,在之前的时光中,我与大家共同学习了JavaSE,数据结构和数据库,学习的道路上有你们的陪伴和支持,我感到十分的开心和荣幸,希望在以后的日子里大家一起进步一起努力!!❤🐱🚀🐱🚀🐱🚀今天呢,我们将开始学习JavaEE初阶的内容,感谢一路走来大家的支持和关心🍉🍉🍉,博主以后会更加努力的为大家带来更精彩的文章,感谢支持,如果觉得文章不错的,多多点赞支持哟🍉🐥
文章目录
- 🚩进程
-
- 🚩在区分进程和线程的区别和联系之前我们先了解什么是进程
- 🚩什么是进程
- 🚩操作系统如何处理进程
- 🚩PCB是什么
- 🚩PCB 中的一些属性
- 🚩什么是进程调度?它包含了那些属性
-
- 🚩并行和并发
- 🚩进程的独立性是什么
- 🚩进程间的通信
- 🍉线程
-
- 🍉线程是什么?
- 🍉线程在并发编程上和进程的区别
- 🍉为什么线程比进程更轻量?进程重量重在哪里?
- 🍉经典面试题
- 🍉谈谈进程和线程的区别和联系
🚩进程
🚩在区分进程和线程的区别和联系之前我们先了解什么是进程
🚩什么是进程
狭义定义:进程就是一段程序的执行过程。
广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
举个例子:打开任务管理器我们可以看到许多程序正在运行,这里顺别截取一张图方便大家理解
这些 .exe
都称为"可执行文件",这些可执行文件,都是文件,都是静静的躺在硬盘上的,在你双击之前,这些文件不会对你的系统有任何的影响,但是,一旦你双击执行这些 exe 文件,操作系统就会把这个 exe 给加载到内存中,并且让CPU开始执行exe内部的一些指令,这个时候,就已经把 exe 给执行起来,他就不再是躺平的咸鱼,而是开始进行了一些具体的工作,把这些运行起来的 可执行文件,称为 "进程"
以下都是我这个机器上运行的进程
🚩操作系统如何处理进程
1.先描述一个进程(明确出一个进程上面的一些相关属性)
操作系统里面主要是通过 C/C++ 来实现的,此处的描述其实就是用的C语言中的"结构体"(操作系统中描述进程的这个结构体,称为"PCB"(process control block)进程控制块)
2.再组织若干个进程(使用一些数据结构,把很多描述进程的信息给放到一起,方便进行增删改查)
典型的实现就是使用双向链表来把每个进程的PCB给串起来
1.所谓的"创建进程",就是先创建出 PCB,然后把 PCB 加到双向链表中
2.所谓的"销毁进程",就是找到链表上的 PCB,并且从链表上删除
3.所谓的"查看任务管理器"就是遍历链表
🚩PCB是什么
描述进程的这个结构体,称为"PCB"(process control block)进程控制块)
🚩PCB 中的一些属性
1.pid
pid(进程id)进程的身份标识
2.内存指针
指明了这个进程要执行的代码.指令在内存的哪里,以及这个进程执行中依赖的数据都在哪里
3.文件描述符表
程序在运行过程中,经常要和文件打交道(文件是在硬盘上的),进程每次打开一个文件,就会在文件描述符表上多增加一项(这个文件描述符表就可以视为一个数组,里面的每个元素又是一个结构体,就对应一个文件的相关信息),这个文件描述符表的下标,就称为文件描述符
一个进程只要一启动,不管你代码中是否写了打开/操作文件的代码,都会默认的打开三个文件(系统自动打开的)
1.标准输入(System.in)
2.标准输出(System.out)
3.标准错误(System.err)
上面的属性是一些基础属性,下面的属性,主要是为了能够实现进程的调度
🚩什么是进程调度?它包含了那些属性
1.什么是进程调度
用通俗的话来将就是:一个系统同一时间,执行了很多任务,这件事就是所谓的"进程调度"(进程的调度,其实就是操作系统 在考虑CPU资源如何给各个进程分配~~)
2.包含的属性
在讲属性的时候先给大家举个例子便于大家理解:首先所谓的调度就是"时间管理"
假设博主是一个妹子,长得好看,并且身材也好(假设的哈,博主是男的),还会说话的妹子,这导致了我有很多的追求者,原则上来说,同一时刻,我只能谈一个男朋友,但是我现在同时谈了多个男朋友,假设同时谈了三个男朋友.A.有钱的 B.长得帅的 C.有钱又帅的 因此,就需要合理的管理时间,避免同一时刻,这三个人碰面~我就可以安排一个时间表:
周一:和 A 去逛街
周二:和 B 去上课
周三:和 C 去看电影
周四…
2.1状态
这个状态就描述了当前这个进程接下来应该怎么调整
1.就绪状态:随时可以去CPU上执行
2.阻塞状态/睡眠状态,暂时不可以去CPU上执行
2.2优先级
先给谁分配时间,后给谁分配时间,以及分给谁分的多,谁分的少
2.3记账信息
统计了每个进程,都分别被执行了多久,分别都执行了那些指令,分别都排队等了多久…给进程调度提供指导依据
2.4上下文
表示了上次进程被调度出CPU的时候,当时程序的执行状态,下次进程上CPU的时候,就可以恢复之前的状态,然后继续往下执行
进程被调度出CPU之前,要先把CPU中的所有的寄存器的数据都给保存到内存中相当于存档
下次进程再被调度到CPU的时候,就可以从刚才的内存中,恢复这些数据到寄存器中,相当于读档了
通俗的讲:
存档+读档 存档存储的游戏信息,就称为"上下文"
🚩并行和并发
并行:微观上,两个CPU核心,同时执行两个任务的代码
并发:微观上,一个CPU核心,先执行一会任务1,再执行一会任务2,再执行一会任务3…再执行一会任务1,只要切换的足够快,宏观上看起来就好像这么多任务同时在进行
并行和并发这两件事,只有在微观上有区分,宏观上我们去分不了
🚩进程的独立性是什么
由于操作系统上,同时运行着很多个进程,如果某个进程,出现了BUG,进程崩溃了,是否会影响到其他进程呢?
进程的独立性保证了如果出现bug不会影响到其他进程,能够做到这一点就是"进程独立的独立性"来保证的,并且依赖了"虚拟地址空间"
🚩进程间的通信
操作系统中,提供的"公共空间"有很多种,并且各有各的特点~有的存储空间大,有的小,有的速度快,有的速度慢,操作系统中提供了多种这样的进程间通信机制
现在最主要使用的进程通信方式:
1.文件操作
2.网络操作(socket)
🍉线程
🍉线程是什么?
线程是进程的一个执行路径,一个进程中至少有一个线程,进程中的多个线程共享进程的资源。
举个通俗的列子:进程
好比是一个工厂,而线程
则是工厂里面的生产线,一个工厂里面可以有一个生产线,和多个生产线
🍉线程在并发编程上和进程的区别
通过多进程,我们可以实现并发编程,但是有个问题,如果需要频繁的创建/销毁进程,这个事情成本是比较高的,如果需要频繁的调度进程,这个事情成本也是比较高的
如何解决这个问题呢?
思路有两个:
1.进程池:(数据库连接池,字符串常量池)
进程池虽然能够解决上述问题,提高效率,同时也有问题,池子里的闲置进程,不适用的时候也在消耗系统资源,消耗的系统资源太多了
2.使用多线程来实现并发编程
线程比进程更轻量,每个进程可以执行一个任务,每个线程也能执行一个任务(执行一段代码),也能够并发编程
创建线程的成本比创建进程要低得多
销毁线程的成本比创建进程要低得多
调度线程的成本比创建进程要低得多
🍉为什么线程比进程更轻量?进程重量重在哪里?
进程重量重在资源申请释放(在仓库里找东西),线程是包含在进程中的,一个进程中的多个线程,共用一份资源(同一份内存+文件)
🍉经典面试题
🍉谈谈进程和线程的区别和联系
1.进程包含线程,一个进程里可以有一个线程,也可以有多个线程
2.进程和线程都是为了处理并发编程这样的场景
但是进程有问题,频繁创建和释放的时候效率低,相比之下,线程更轻量,创建和释放效率更好
3.操作系统创建进程,是要给进程分配资源,进程是操作系分配资源的基本单位,操作系统创建的线程,是要在CPU上调度执行,线程是操作系统调度执行的基本单位
4.进程具有独立性,每个进程有各自的虚拟地址空间,一个进程挂了不会影响其他进程,同一个进程中的多个线程,共用同一个内存空间,一个线程挂了可能会影响到其他的线程,甚至导致整个进程崩溃