目录
- 1.进程的概念
- 2.如何管理进程
- 3.进程的调度
- 4.并行和并发
- 5.进程调度需要使用的属性
- 6.进程之间的通信
- 7.进程和线程的区别
操作系统是一个软件,对下要管理好各种硬件设备,对上要给各种软件提供稳定的运行环境.这篇博客主要讲解操作系统如何管理进程。
1.进程的概念
进程就是跑起来的程序,如下图的两个的程序,后缀都是以exe结尾,.exe称为可执行文件.
这些可执行文件都是文件,当你没有点击的时候,就会待着硬盘里面,不会对系统有任何影响.当你双击exe文件之后,操作系统就会把exe文件加载到内存,并让CPU开始执行exe文件内部的一些指令,exe文件中存放了很多这个程序的内部指令,双击之后就会开始工作,这些运行起来的可执行文件就叫做进程.
下图就是当前电脑上运行的进程:
线程是进程内部的一个部分,进程包含线程,如果把进程想象成是一个工厂,那么线程就是工厂里的生产线, 一个厂里面可以有一个生产线或者也可以有多个生产线,对于 java 代码来说,最终都是通过 java 进程来跑起来的,此处的这个java进程就是jvm。
2.如何管理进程
操作系统是如何管理进程的呢?
1.先描述这个进程(明确出进程上的一些相关属性). 2.再组织若干个进程(使用一些数据结构,把很多描述进程的信息放到一起,方便增删改查),典型的实现就是使用双向链表,把每个PCB组织起来 操作系统主要是通过C/C++来实现的,C语言中的结构体用于描述操作系统中进程的结构体,叫做PCB,也就是进程控制块. “创建进程”,就是先创建出 PCB,然后把PCB加到双向链表中 “销毁进程”,就是找到链表上的 PCB,并且从链表上删除. “查看任务管理器”就是遍历链表. |
PCB中的一些属性: 1.pid(进程id),进程的身份标识 2.内存指针 3.文件描述符表 |
3.进程的调度
进程的调度是说无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数、这将导致它们互相争夺处理机。另外,系统进程也同样需要使用处理机。这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行。
就是说电脑执行的进程数量很多,但是CPU核数只有6核或者8核,是怎么样分配给进程是运行呢?进程的调度其实就是操作系统在考虑 CPU 资源如何给各个进程分配。
内存资源又是如何分配的呢?利用虚拟地址空间,当处理器读取或写入内存位置时,它会使用虚拟地址。 在读取或写入操作过程中,处理器会将虚拟地址转换为物理地址,由于操作系统上,同时运行着很多个进程,如果某个进程,出现了bug,进程崩溃了,是否会影响到其他进程呢? 现代的操作系统(windows, linux, mac…).能够做到这一点就是“进程的独立性”来保证的.就依仗了“虚拟地址空间”
4.并行和并发
并行和并发: 并行:微观上,两个 CPU 核心,同时执行两个任务的代码 并发:微观上, 是一个CPU 核心,先执行一会任务1,再执行一会任务2,再执行一会任务3,再执行一会任务1,只要切换的足够快,宏观上看起来, 就好像这么多任务在同时执行一样。 并行和并发这两件事,只是在微观上有区分,宏观上区分不了,微观上的区分都是操作系统自行调度的结果. 假设CPU有6个核心,同时跑20个任务,这 20个任务,有些是并行的关系,有些是并发的关系可能任务A 和 任务B,一会是并行,一会是并发,都是微观上操作系统在控制的,在宏观上是感知不到 正因为在宏观上区分不了并行并发,在写代码的时候也就不去具体区分这两个词,实际上通常使用“并发”这个词,来代指并行 + 并发. |
5.进程调度需要使用的属性
进程调度需要使用的属性: 1.状态,状态就描述了当前这个进程接下来应该怎么调度,就绪状态: 随时可以去 CPU 上执行.阻塞状态/睡眠状态: 暂时不可以去 CPU 上执行。 2.优先级:先给谁分配时间,后给谁分配时间.以及给谁分的多,给谁分的少. 3.上下文:表示上次进程被调度出 CPU 的时候当时程序的执行状态,下次进程上 CPU 的时候就可以恢复之前的状态,然后继续往下执行. 4.记账信息: 统计每个进程都分别被执行了多久,分别都执行了哪些指令,分别都排队等了多久了,给进程调度提供指导依据的. |
进程的状态: 1.创建状态:进程在创建时需要申请一个空白PCB,向其中填写控制和管理进程的信息,完成资源分配。如果创建工作无法完成,比如资源无法满足,就无法被调度运行,把此时进程所处状态称为创建状态 2.就绪状态:进程已经准备好,已分配到所需资源,只要分配到CPU就能够立即运行 3.执行状态:进程处于就绪状态被调度后,进程进入执行状态 4.阻塞状态:正在执行的进程由于某些事件(I/O请求,申请缓存区失败)而暂时无法运行,进程受到阻塞。在满足请求时进入就绪状态等待系统调用 5.终止状态:进程结束,或出现错误,或被系统终止,进入终止状态,无法再执行 |
6.进程之间的通信
进程之间现在通过虚拟地址空间,已经各自隔离开了,但是在实际工作中,进程之间有的时候还是需要相互交互的.
操作系统提供了类似的“公共空间",进程A就可以把数据见放到公共空间上.进程B再取走.操作系统中,提供的“公共空间”有很多种并且各有特点,有的存储空间大,有的小,有的速度快,有的慢,操作系统中提供了多种这样的进程间通信机制现在最主要使用的进程间通信方式有两种1.文件操作2.网络操作(socket)
为啥要有进程?因为我们的系统支持多任务了,程序通过多进程,是完全可以实现并发编程的,但是有点小问题如果需要频繁的创建/销毁进程,这个事情成本是比较高的.如果需要频繁的调度进程,这事情成本也是比较高的,创建进程就得分配资源,销毁进程也得释放资源对于资源的申请和释放本身就是一个比较低效的操作,
如何解决这个问题?思路有两个:
1.进程池(数据库连接池字符串常量池)
进程池虽然能解决上述问题,提高效率,同时也有问题,池子里的闲置进程,不使用的时候也在消耗系统资源.消耗的系统资源太多了
2.使用线程来实现并发编程
线程比进程更轻量每个进程可以执行一个任务.每个线程也能执行一个任务(执行一段代码),也能够并发编程.创建线程,的成本比创建进程要低很多,销毁线程的成本也比销毁进程低很多在 Linux 上也把 线程 称为 轻量级进程(LWP light weight process),调度线程的成本也比调度进程低很多
为啥线程比进程更轻量?进程重量是重在哪里? 重在资源申请释放(在仓库里找东西…)线程是包含在进程中的.一个进程中的多个线程,共用同一份资源(同一份内存+文件)只是创建进程的第一个线程的时候(由于要分配资源),成本是相对高的,后续这个进程中再创建其他线程,这个时候成本都是要更低一些, 不必再分配资源了
多加一些线程是不是效率就会进一步提高呢?一般来说是会,但是也不一定,如果线程多了,这些线程可能要竞争同一个资源,这个时候,整体的速度就收到了限制.
7.进程和线程的区别
谈谈进程和线程的区别和联系 1.进程包含线程一个进程里可以有一个线程,也可以有多个线程 2.进程和线程都是为了处理并发编程这样的场景,但是进程在频繁创建和释放的时候效率低,相比之下,线程更轻量,创建和释放效率更高,因为进程少了申请和释放资源的过程 3.操作系统创建进程要给进程分配资源,进程是操作系统分配资源的基本单位操作系统创建的线程,是要在CPU 上调度执行.线程是提作系统调度执行的基本单位,每个进程里,只有一个线程,可以视为是在调度进程.但是如果进程里有多个线程.更严谨的说法还是以线程为单位进行调度 4.进程具有独立性,每个进程有各自的虚拟地址空间,一个进程挂了,不会影响到其他进程同一个进程中的多个线程,共用同一个内存空间, 一个线程挂了,可能影响到其他线程的,甚至导致整个进程崩溃. |