一:进程对内存的管理
1:进程的独立性:
进程是如何管理内存的,核心:每个进程都有一块独立的内存,进程与进程之间的内存互不干扰,通常情况下,进程A的内存不能访问进程B的内存
好处“进程独立性”:如果进程A的内存超出了给分配的内存大小(即内存越界)或者出现某些bug导致进程A挂掉,不会影响到进程B的运行
二:“进程间的通信”
引入:虽然进程有独立性,但是有一些任务还需要进程与进程之间进行相互配合去完成
1:内存中的公共空间
进程与进程之间也可以通信,操作系统会在内存当中开辟一块特殊的公共空间,用来进程与进程之间进行“数据交换”,这与进程的“独立性”并不冲突。
2:网络通信
操作系统中提供的“进程间的通信”并不限于上述,在Java中,我们通常以文件和网络的形式来达到“进程间的通信”。后端也大同小异,一般是一组服务器之间进行通信
网络通信(简述)同一台计算机中的不同进程可以通过网络来进行通信,不同计算机的不同进程也可以达到通信的目的(泛用性更广)
三:进程的缺点
引入:对进程的管理和调度(对进程的调度)
前面我们已经学过,像单任务操作系统,并不需要考虑进程这个概念,即不需要对进程进行管理和调度。但是现在的操作系统一般都是多任务操作系统,在一些特殊的场景下,比如任务超多的时候,我们需要频繁地创建和销毁进程时,进程就暴露出它的缺点了。
1:背景
在早期web开发的时候,PHP为前端霸主,当时的开发语言是C,开发服务器是基于一种叫(CGI)的技术来实现的,这种技术的模式是,多进程的编程模式。
即服务器会在同一时刻收到许多请求,服务器基于每一个请求都会申请创建一个进程,然后为请求提供服务,服务完毕后返回响应,销毁进程释放资源。
这个过程中包含着大量频繁的进程的创建和销毁,但是进程的创建和销毁并不容易
2:索取内存资源
进程在创建之前,第一个要索取的资源就是内存。
过程:所以首先就需要向系统申请一块指定大小的内存资源,系统知道后就把所有空闲的内存块通过数据结构组织在一起,然后再在里面查找一个大小合适的内存,最后分配给进程,进程再把依赖的代码和数据通过硬盘加载到内存当中,
四:线程
引入:
通过以上线程缺点的描述,我们针对“频繁创建和释放线程需要消耗大量的资源”这一问题,提出了“线程”这一概念来解决。
1:线程的概念和特点
线程也叫“轻量化进程”,线程在进程的基础上,保留了原有的独立调度执行的特点,这种“并发支持”,解决了“申请资源”和“释放资源”带来的额外开销这一问题。
回顾内存指针:在pcb中有一个属性叫内存指针,它可以指向一块内存空间,(即为pcb确定内存空间位置)
回顾进程的独立性:进程与进程间申请的内存空间是彼此独立的,内存空间互不干涉
2:进程在内存中的分配方式
在一个进程当中可以包含多个进程(即图中用一个大进程包含两个小进程来形象描述,可以理解成“进程组”),每个进程都是由pcb来描述的。对于每一个进程来说,它们分配的内存空间是独立的,互不干涉(即pcb的内存指针与内存空间都是一一对应的)
3:线程在内存中的分配方式
对于线程来说就不一样了,可以有多个线程的pcb指向同一块内存空间,重点来了!!!
这就意味着,第一个线程申请了内存空间后,后面的线程就不必在申请了,同样的第一个线程释放资源后,这块内存空间也不必回收,可以留着后面再复用(即多个线程共用一份资源)
同样线程中的pcb也有进程pcb的这些概念(状态,优先级,上下文,记账信息)
4:进程和线程的结合
5:进程和线程之间的关系
每个进程都可以包含一/多个线程,像有三个小线程的小pcb都指向了a,它们获取a中的代码指令的用途不一定相同(即各取所需)有一个线程申请了a这一块空间后,后面的线程就不必在申请了,大大降低了频繁申请空间和释放空间带来的资源浪费
6:线程的缺点
(1)设置线程是有限的
对于上述现成的了解,引入线程不仅可以大大提高进程运行的效率,也可以降低资源浪费,但是引入的线程是越多越好吗?不,有两个问题需要我们注意
①线程数量问题
看图四,有三个pcb的红色箭头(内存指针)指向内存a,共用内存a上的代码指令,那么如果增加箭头数呢(即有10个,100个pcb的内存指针指向a)此时线程与线程之间就会争夺cpu的内存空间,非但不会提高效率,反而会大大增加线程调度所耗费的资源。
②线程间优先级问题
看图四,有三个pcb的红色箭头(内存指针)指向内存a,共用内存a上的代码指令,那么涉及到一个问题,究竟“谁先用,谁后用”,线程和线程之间谈不拢就打一架呗,就可能会导致代码出现一些bug和逻辑上的错误(这就涉及到了线程的安全问题)!!
③线程异常问题
还是看图四:在②的基础上,A线程和B线程谈不拢打了一架,A线程打赢了,说:a内存上代码指令老子就先用了。B不服气,王德发!不让我用,那大家都别用了!!!于是B抛出异常,导致整个大进程都被终止了
7:前后对比
在有线程之前
进程所扮演的角色:既是资源分配的基本单位,也是执行调度的基本单位
在有线程之后
进程专注于资源分配(超大进程去申请B这一块空间)如4的图
线程专注于调度执行(线程去调度内存中的数据、代码)如4的图
标签:诞生,JavaEE,内存空间,调度,pcb,线程,内存,进程 From: https://blog.csdn.net/2301_80133875/article/details/1423063228:总结
①两个基本单位
进程包含线程,进程是“资源分配”的基本单位,线程是“执行调度”的基本单位
②资源共享
每一个进程都有自己独立的资源(内存空间和文件描述符表),进程所包含的线程可以共享这一份资源
③独立执行
每一个线程都是一段独立的执行流,可以独立的被cpu进行调度(状态,上下文,文件描述符表,优先,记账信息,线程都有自己独立的一份)
④数量限制
线程不是越多越好,如果线程太多,执行调度的开销就会很大(船上装不下这么多人)
⑤线程安全
同一个进程中的线程可能会相互干扰(抢夺资源),引起线程安全问题(一条船上抢东西吃)
⑥线程异常
同一个进程中的线程如果抛出异常,会影响到其它线程,可能会把整个进程中的所有线程都异常终止(一条船上的人,要死一起死)