前两章节已经详细的向大家介绍过进程(学习笔记-进程详细介绍)和线程(学习笔记-线程详细介绍)。本文旨在向大家详细的介绍进程-线程-协程的基本关系。
基本概念进程
进程是具有一定独立功能的程序在某个数据集合上的一次运行过程,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。
线程
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存。上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。
协程
协程是一种用户态的轻量级线程,协程的调度完全由用户控制。与子例程一样,协程也是一种程序组件。相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。
并行与并发并发
并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。
并行
并行是指"并排行走"或"同时实行或实施"。在操作系统中是指,一组程序按独立异步的速度执行,不等于时间上的重叠(同一个时刻发生)。要区别并发。并发是指:在同一个时间段内,两个或多个程序执行,有时间上的重叠(宏观上是同时,微观上仍是顺序执行)
并发和并行从宏观上来讲都是同时处理多路请求的概念。但并发和并行又有区别,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。 并发的设计使到并发执行成为可能,而并行是并发执行的其中一种模式。
并行与并发
简单理解进程
进程的出现是为了更好地利用CPU资源使到并发成为可能。 假设有两个任务A和B,当A遇到I/O操作,CPU默默地等待任务A读取完操作再去执行任务B,这样无疑是对CPU资源的极大的浪费。于是人们就在想如果在任务A读取数据时,让任务B执行,当任务A读取完数据后,再切换到任务A执行。注意关键字切换,那么这就涉及到了状态的保存,状态的恢复,加上任务A与任务B所需要的系统资源(内存,硬盘,键盘等等)是不一样的。自然而然地就需要有一个东西去记录任务A和任务B分别需要什么资源,怎样去识别任务A和任务B等等。于是进程就被发明出来了。通过进程来分配系统资源,标识任务。如何分配CPU去执行进程称之为调度,进程状态的记录,恢复,切换称之为上下文切换。进程是系统资源分配的最小单位,进程占用的资源有:地址空间,全局变量,文件描述符,各种硬件等等资源。
线程
线程的出现是为了降低上下文切换的消耗,提高系统的并发性,并突破一个进程只能干一样事的缺陷,使到进程内并发成为可能。假设,一个文本程序,需要接受键盘输入,将内容显示在屏幕上,还需要保存信息到硬盘中。若只有一个进程,势必造成同一时间只能干一样事的尴尬(当保存时,就不能通过键盘输入内容)。若有多个进程,每个进程负责一个任务,进程A负责接收键盘输入的任务,进程B负责将内容显示在屏幕上的任务,进程C负责保存内容到硬盘中的任务。这里进程A,B,C间的协作涉及到了进程通信问题,而且有共同都需要拥有的东西—文本内容,不停的切换造成性能上的损失。若有一种机制,可以使任务A,B,C共享资源,这样上下文切换所需要保存和恢复的内容就少了,同时又可以减少通信所带来的性能损耗,那就好了。是的,这种机制就是线程。线程共享进程的大部分资源,并参与CPU的调度, 当然线程自己也是拥有自己的资源的,例如,栈,寄存器等等。 此时,进程同时也是线程的容器。线程也是有着自己的缺陷的,例如健壮性差,若一个线程挂掉了,整一个进程也挂掉了,这意味着其它线程也挂掉了,进程却没有这个问题,一个进程挂掉,另外的进程还是活着。
协程
协程通过在线程中实现调度,避免了陷入内核级别的上下文切换造成的性能损失,进而突破了线程在IO上的性能瓶颈。 当涉及到大规模的并发连接时,例如一万连接。以线程作为处理单元,系统调度的开销还是过大。当连接数很多,需要大量的线程来干活,可能大部分的线程处于Ready状态, 系统会不断地进行上下文切换。既然性能瓶颈在上下文切换,那解决思路也就有了,在线程中自己实现调度,不陷入内核级别的上下文切换。
总结:
进程出现优化了CPU的调度。CPU(单核)与进程对应关系为一对一。
线程出现优化了进程的调度。进程与线程对应关系为一对多。
协程出现优化了线程的调度。线程与协程对应关系为一对多。
进程-线程-协程关系
拓展:
(1)单CPU中进程只能是并发,多CPU计算机中进程可以并行。
(2)单CPU单核中线程只能并发,单CPU多核中线程可以并行。
(3) 无论是并发还是并行,使用者来看,看到的是多进程,多线程。
区别与联系区别
1. 操作级别:进程,线程是操作系统级的,协程是语言级的。
2. 机制:进程,线程是同步机制,而协程则是异步机制。
3. 空间:进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈。线程拥有自己独立的栈和共享的堆,共享堆,不共享栈。协程和线程一样共享堆,不共享栈。
4. 属性:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
5. 资源分配:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。进程所维护的是程序所包含的资源(静态资源), 如:地址空间,打开的文件句柄集,文件系统状态,信号处理handler等;线程所维护的运行相关的资源(动态资源),如:运行栈,调度相关的控制信息,待处理的信号集等;
6. 系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。但是进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个进程死掉就等于所有的线程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。
7. 耗时:线程上下文切换比进程上下文切换耗时更短。线程创建和销毁所需要的时间比进程小很多。
8. 属性:线程有自己的私有属性TCB,线程id,寄存器、硬件上下文,而进程也有自己的私有属性进程控制块PCB,这些私有属性是不被共享的,用来标示一个进程或一个线程的标志
9. 使用场景:IO密集型一般使用多线程或者多进程,CPU密集型一般使用多进程。
联系(1)协程是一种用户态的轻量级线程,线程是轻量级的进程
(2)一个进程包含多个线程,一个线程包含多个协程。
(3)同一个进程中可以包括多个线程,并且线程共享整个进程的资源(寄存器、堆栈、上下文)。线程是进程内的一个执行单元,进程内至少有一个线程,线程才是真正的运行单位。它们共享进程的地址空间,而进程有自己独立的地址空间。
(4)进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束
本文的初衷为学习笔记的分享,部分图文来源于网络,如侵,联删。
,