进程、线程与协程

进程

进程的出现是为了更好的利用CPU资源使到并发成为可能。 假设有两个任务A和B,当A遇到IO操作,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上的性能瓶颈。 当涉及到大规模的并发连接时,例如10K连接。以线程作为处理单元,系统调度的开销还是过大。当连接数很多 —> 需要大量的线程来干活 —> 可能大部分的线程处于ready状态 —> 系统会不断地进行上下文切换。既然性能瓶颈在上下文切换,那解决思路也就有了,在线程中自己实现调度,不陷入内核级别的上下文切换。说明一下,在历史上协程比线程要出现得早,在1963年首次提出, 但没有流行开来。为什么没有流行,没有找到信服的资料,先挖个坑,以后那天了解后,再补上。

小结

进程,线程,协程不断突破,更高效的处理阻塞,不断地提高CPU的利用率。但是并不是说,线程就一定比进程快,而协程就一定不线程要快。具体还是要看应用场景。可以简单粗暴的把应用分为IO密集型应用以及CPU密集型应用。

多核CPU,CPU密集型应用
此时多线程的效率是最高的,多线程可以使到全部CPU核心满载,又避免了协程间切换造成性能损失。当CPU密集型任务时,CPU一直在利用着,切换反而会造成性能损失,即便协程上下文切换消耗最小,但也还是有消耗的。

多核CPU,IO密集型应用
此时采用多线程多协程效率最高,多线程可以使到全部CPU核心满载,而一个线程多协程,则更好的提高了CPU的利用率。

单核CPU,CPU密集型应用
单进程效率是最高,此时单个进程已经使到CPU满载了。

单核CPU,IO密集型应用
多协程,效率最高。例如,看了上面应该也是知道的了

作者:Ljian1992
链接:http://www.jianshu.com/p/f11724034d50
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

猜你喜欢

转载自blog.csdn.net/xiang12835/article/details/76424773