目录
一.什么是进程
简单来说,进程就是一些跑起来的程序,在文件里面我们常常可以看到一些.exe文件,这些都称为"可执行文件",一旦执行这些文件,操作系统就会把这个.exe文件加载到内存里,并CPU会执行这个文件内部的一些指令,此时这个文件就不再是静态的了,而已经变成一个动态的了,然后这些运行起来的应用程序就是进程了,可以在任务管理器里面看到的,这些都是进程。
二.操作系统如何管理进程
1.首先要描述一个进程(明确一个进程上面的一些相关属性(pid,内存指针,文件描述符表),主要是操作系统通过使用c/c++的"结构体"(进程控制块PCB)(也就和java中的类一样)来进行描述的)
2.再组织若干个进程(典型的实现:使用双向链表把进程上面的信息(PCB)串起来,方便进行增删查改)
所谓的"创建进程"就是线程间出PCB,然后再把PCB加到双向链表中去
所谓的"销毁进程"就是找到链表上的PCB,从链表上进行删除
所谓的"查看任务管理器"就是遍历这个链表
进程之间是相互独立的,这是"进程的独立性(依仗虚拟地址空间)",但也不是不能交互的,操作系统提供了很多种"公共空间"(一般是文件操作和网络操作),进程A将数据放到公共空间,然后进程B再取走,这就是进程间通信
PCB内部的属性(进程调度)
1.pid
就是进程的id,对进程进行身份识别的id
2.内存指针
指明了进程所要执行的代码/指令的内存,以及此进程所需要的数据(.exe启动后操作系统就会把.exe加载到内存中去,变为进程)
3.文件描述符表
一个进程只要启动,无论进行什么操作都会打开标准输入,标准输出,标准错误三个文件,另外只要进程每打开一个文件,文件描述符表上就会增加一项
上面的都是一些简单的属性,下面的属性都是为了实现进程调度(在有限的核心内能同时执行多个任务(并行(微观上两个CPU核心同时执行两个任务)和并发(一个CPU核心先执行一下第一个任务再执行第二个任务,等一会又再回来执行第一个任务,但这都是在很短的时间内,如果切换够快的话,宏观上就可以看出是两个任务在同时执行))所以在实际使用上使用并发来代指并行+并发)
进程调度(可以理解为时间管理):进程调度程序是操作系统的真正核心,它直接负责CPU的分配。系统中所有进程都是在CPU上运行的,进程调度就是它们的切换开关
基本过程:
①.根据进程的状态对进程进行调度
②.安排进程的先后顺序以及时间长短
③.将进程的各种操作记录下来
④.保存进程的信息以及读取进程
4.状态
描述了当前的进程能否被执行
就绪状态:随时可以执行
阻塞状态/睡眠状态:暂时不可以去CPU上执行
...
5.优先级
多个任务,先给谁分配时间,后给谁分配时间,谁的时间多,谁的时间少,就是优先级
6.记账信息
统计每个进程分别执行了多久,分别执行了哪些指令或者排队了多久
给进程调度提供指导依据
7.上下文
表示上次进程被调度出CPU的状态,下次进程上CPU的时候就可以恢复此前的状态,就看继续往下执行了~~
类似于存档 + 读档
进程被调出CPU之前,要先把CPU中的所有寄存器中的数据给保存到内存中相当于是存档
下一次进程再被调度上CPU的时候,就可以从内存中恢复到寄存器中,这就是读档
三.什么是线程,关于线程
线程是进程内部的一个部分,进程包含线程,如果把进程想象为一个工厂的话,那么线程就是工厂内部的生产线,一个工厂可以有一个生产线,当然也可以有多个生产线
由于系统支持多任务,因此我们需要"并发编程",通过多进程是完全可以实现并发编程的,但要是频繁的创建/销毁进程的话,成本是非常高的,频繁的调度进程成本也是很高的,创建进程是需要对资源进行申请的(内存和文件),而销毁进程则需要释放资源(内存和文件),这本身就是非常低效的
那如何解决这个问题:
1.进程池:虽然能解决这个问题,但是消耗的资源太多了,池内闲置的进程还是很多
2.使用线程来实现并发编程:线程比进程更加轻量,每个线程执行一个任务,也可以并发编程,创建销毁,调度线程成本都是低于进程的(进程需要去申请释放资源的,线程包含在进程中,公用一份资源,再创建线程不必再分配资源了,但是并不说线程越多越好,在任务比较少的时候,多线程反而会降低效率)
四.进程和线程的区别和联系
1.进程包含线程,一个进程可以有一个线程也可以有多个线程
2.进程和线程都是为了处理并发编程这样的场景
但是进程耗费的成本较高,相比之下线程更轻量(创建线程不必再分配资源了)
3.操作系统创建进程,要给进程分配资源,进程是操作系统分配资源的基本单位
操作系统创建线程,是要在CPU上调度执行的,线程是操作系统调度线程执行的基本单位
4.进程有独立性每个进程都有各自的虚拟地址空间,一个进程出现问题,不会影响到其他进程
而同一个进程中的多个线程同用一个内存空间,如果一个线程出现问题,很可能会影响到其他线程也有可能直接使整个进程"挂掉"