目录
进程和线程的区别
1. 一个进程包含一个线程或多个线程。
2. 进程和线程都是为了实现 “并发编程” 的效果,但是线程相对于进程来说更轻量级,更高效。
3. 同一个线程之间,通用一根资源(内存+硬盘),省去了 申请/释放的资源开销、
4. 进程和进程之间是具有隔离性的,进程A挂了,是无法影响到其他的进程的。
线程和线程之间,线程A挂了,有可能导致线程B也跟着一起挂掉,进而导致程序崩溃(线程安全问题 + 线程出现异常)
5. 进程是资源分配的基本单位,线程是调度执行的基本单位。
...待更新
要想了解进程和线的区别,我们就得先搞清楚是进程什么是线程
1. 进程
进程的基本概念
一个线程是一个跑起来的 .exe 文件,而不是一个 .exe 文件。
我们可以右击任务栏,打开任务管理器,可以查看我们电脑的进程有哪些。
以下的每一条都是一个进程,除了我们开启的程序进程外,还有很多系统的进程。
进程的管理角度
描述:使用类/结构体,把被管理的对象,各个属性都表示出来。
组织:使用数据结构(双向链表),把这些表示出来的对象,串起来(为了方便对后续对进程进行增删查改的操作)
系统中专门有一个结构体(操作系统内核是使用 C/C++ 来实现的)描述进程的属性
这个结构体被称之为 PCB(进程控制块)
一个进程是由一个或者多个 PCB 来表示的
系统中会使用类似双向链表这样子的数据结构来组织多个PCB
进程的创建和销毁
创建进程:就是创建 PCB ,并且将PCB插入到链表当中
销毁进程:就是将 PCB 从链表中删除
展示进程:就是遍历链表的每一个节点
PCB 的部分基本属性
要想进一步了解进程的详细特性,我们还需要了解以下 PCB的基本属性
1)pid 进程的身份表示
每个进程都有一个pid,同一时刻,不同进程的pid是不一样的。
如下图,我们打开认为管理器查看详细今夕就可以查看到进程的pid
2) 内存指针(进程持有的内存资源)
每个进程在创建的时候都会分配一定的内存空间,
3)文件标识符表(进程次有点硬盘资源)
- 文件操作符表就是描述进程持有的 “硬盘资源” 的状态是类似于 顺序表这样子的数据结构。
- 一个进程需要设计到硬盘相关的操作,就需要按照文件的方式来操作。
- 文件操作符表就是记录当前进程关联的文件有哪些,都能操作什么文件。
进程的基本属性
1)进程的状态
1. 进程的就绪状态
进程正在CPU上运行。
进程虽然没有在CPU上运行,但是时刻在等待上CPU上运行。
2. 进程的堵塞状态
进程缺少某些特定的执行条件,无法满足运行条件运行,导致堵塞。
例如:程序等待用户输入输入,如果用户一直不输入,进程就会堵塞。
进程的状态还有很多种状态。。。
2)进程的优先级
操作系统在调度进程的时候并非是一视同仁的,有的优先级高,有的优先级低,优先级高的优先调度。
例如:一个电脑上同时运行游戏(优先级较高)和QQ(优先级较低)
QQ晚收到消息几秒钟都是没问题的,但是游戏卡顿两秒钟都是无法接受的。
3)进程的上下文(记录进程离开前的信息,存储到内存当中)
可以粗暴理解成 存档 和 读档
记录进程从CPU离开前的各种寄存器,将寄存器存储到内存当中,等下次进程回到CPU上的时候,就可以通过寄存器的值恢复到过去,继续执行上次未完成的任务。
寄存器的类型
1. 保存当前执行到哪个指令的寄存器(程序计数器)
是一个2/4/8 字节的整数,存储的是一个 内存地址(程序下一条要执行的指令所在的位置)
exe 内包含了指令和数据,把 exe 运行起来,操作系统就会把指令和数据加载到内存中(内存地址)
CPU 就会先从内存中读取指令,然后再执行指令,简单的情况下,程序计数器就会指向进程的入口(简单粗暴想象成main方法也是可以的)
每次取完一条指令,程序计数器的值就会自动跟新,默认情况下是指向吓一条指令(顺序程序)
但是如果遇到跳转类的指令(jmp,jcmp,call..)就会设置成跳转到的地址。
2. 维护栈相关的寄存器
通过一组(一般是两个寄存器)维护当前程序的 “调用栈”。
ebp 指向栈底 esp指向栈顶 修改esp的值就可以实现 “入栈”/“出栈” 的相关操作。(push指令完成上述操作)这样子才能知道一个方法执行完毕后,回到哪里执行。
栈也是CPU的一块内存,这个内存就保存着这个程序的方法调用过程中的一些列关系(也包含局部变量和方法的参数....)
3. 其他通过寄存器,一般是用来存储中间结果的
例如:10 + 20 + 30
假设 10 + 20 算完后,还没来得及加上30 进程就调度走了,就需要把保存10+20的寄存器的值给备份到上下文当中。
线程(Thread)
1)线程是什么?
一个线程就是一个执行流,每个执行流都可以独立的完成一些列的代码。
2)为什么需要线程?
虽然我们有了进程,但是相比于进程来说,线程还是太笨重了。
进程在 创建/销毁 的时候,需要 申请/释放 资源。(相对于线程来说耗时太久了)
线程在创建和销毁的时候,是不需要额外的去 申请/释放 资源的,线程是共享进程的内存资源和硬盘资源的。
3)进程和线程有什么区别?
进程是使用PCB表示的,一个进程可以有一个PCB或者多个PCB来表示。
每个PCB对应着一个线程,每个线程都有(状态,优先级,上下文,记账信息等),除此之外,线程还共享着进程的pid,内存指针,文件描述符表等,线程也跟进程共用同一份内存的。
总结
一个进程可以由一个/多个PCB表示,一个PCB对应着一个线程,每个线程都有自己的状态,上下文,优先级,记账信息等 => 每个线程都可以独立到 CPU 上进行调度 => 这些PCB共用了进程的内存指针和文件描述符表 => 创建线程(PCB)就无需重新申请资源了 => 创建/销毁的效率更高了。
进程是资源分配的基本单位。
线程是调度执行的基本单位。