『面试问答』:进程、线程和协程的区别是什么?
进程 VS 线程
进程是程序的一次执行过程,是操作系统进行资源分配和调度执行的基本单位。
线程是进程内的执行单元,是程序执行的最小单位。
区别主要如下
-
资源占用上 进程是独立的执行单位,拥有独立的内存空间和系统资源,包括文件描述符、进程上下文等; 而线程是进程内的实体,共享进程的资源,每个线程有自己的程序计数器、栈空间和私有数据;
-
调度与切换代价 进程切换需要保存和恢复的状态较多,开销较大; 而线程的切换相对较轻量,只需要保存和恢复栈和寄存器的状态;
-
通信与同步 进程间通信需要使用操作系统提供的进程间同步机制:如管道、共享内存、消息队列等; 线程可以通过共享内存来进程数据交换与通信,同时也需要使用同步机制来避免竞态条件;
-
独立性 进程拥有独立的地址空间,一个进程奔溃后,在保护模式下不会对其他进程产生影响; 而线程共享进程的资源,一个线程的错误可能导致整个进程的崩溃;
协程是啥
协程是一种用户态的,不被操作系统内核所管理,完全由用户控制的,比线程更加轻量级的存在; 一个进程可以由有多个线程,一个线程也可以有多个协程;
用户态执行,性能大大提升:线程的切换由操作系统负责调度,协程由用户自己进行调度,因此减少了上下文切换,提高了效率。
协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到线程的堆区,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以协程的上下文切换非常快。
上下文切换是指?
当一个线程的时间片用完的时候就会重新处于就绪状态让给其他线程使用,这个过程就属于一次上下文切换。
线程在执行过程中会有自己的运行条件和状态(也称上下文),比如程序计数器,栈信息等。
如下情况会出现上下文切换
-
主动让出 CPU,比如调用了
sleep()
,wait()
等。 -
时间片用完,因为操作系统要防止一个线程或者进程长时间占用 CPU 导致其他线程或者进程饿死。
-
调用了阻塞类型的系统中断,比如请求 IO,线程被阻塞。