进程,线程,协程概念

1. 先来对比进程和线程

可以拥有自己的独立资源 切换消耗 是资源分配单位 是执行单元
进程 可以 消耗大
线程 不可以 消耗小

进程是资源容器,我们只会说一个进程占用了多少内存,而从来不会说一个线程占用了多少内存。资源归属于进程,线程却拥有资源的使用权。

线程的概念是建立在进程的基础上的,一个进程至少有一个主线程,有0个或多个子线程,这些线程共用这个进程所申请的资源,因此才会有线程间同步与资源互斥这些概念。由于进程已经是资源分配的单位,因此,进程与进程之间都是相互隔离的,就如同一家一户,各有各的围墙,各有各的宅基地,线程如同家庭里的亲人,这些亲人共同使用家里的资源。

本质上,是线程在执行,进程只是负责申请资源,因此线程才是操作系统调度的最小单位。对于操作系统来说,在进程之间进行切换,就如同从一个住宅切换到另一家住宅,而在线程间切换,就如同从房子的一间卧室切换到客厅。线程间切换要比进程间切换容易的多。

2. 什么是协程

进程,线程是大家非常熟悉的概念,然而说到协程,很多人表示懵逼了,关于协程,要准确掌握以下两个概念

  1. 协程在一个线程中存在
  2. 协程不是系统调度的,而是程序自己负责调度

协程是线程的异步编程模型,因此我才说,协程在一个线程中存在,我特意强调一个线程,是想让你明确一点,系统并没有创建出若干个协程来进行工作,在这个线程中,存在多个子程序,假设有子程序A,B,C,那么最初是A在执行,中途遇到了IO,于是停止A,执行B,然后B中也遇到了IO,这个时候再回来执行A,A执行结束后再执行C

你会看到,在一个线程内,A,B,C三个子程序互相协调工作,这个就是协程。这里所谓的子程序,你可以理解为函数,但是执行过程又不是函数之间的调用,因为代码里,这三个函数并不存在调用关系,他们可能都是在爬取一个url里的内容,各自的运行是独立的,但是子程序在执行过程中发生了中断,将控制权交出,在适当的时候返回来继续执行。

2.1 和线程的对比

线程是系统创建的,具体什么时候执行,执行多久,都是由系统决定的,而协程则是程序自己创建的,在python中,yield 和gevent都可以实现协程。

python的多线程由于存在GIL锁,因此一个时刻只有一个线程在运行,如果你起了10个线程,那么CPU要在这10个线程之间不停的切换,每个线程都有自己的一组CUP寄存器,这里保存了线程的上下文,线程之间的切换是会耗费资源的,线程越多,切换的越频繁,耗费的资源也就越多。

协程之间也存在切换,但是这些协程都是在一个线程中,由程序自身负责切换,而不是CPU负责切换,这种切换相比于线程之间的切换就快的多了,协程拥有自己的寄存器上下文和栈,当需要切换时,将这些内容保存到其他地方,需要切换回来时,将这些内容回复回来,找到上一次离开时所处的逻辑流位置并继续执行。

线程之间对共享资源的访问必须加锁,但协程不需要,原因很简单,协程始终生存在于一个线程中,根本不存在同时修改一个共享资源的情况。

协程是在线程层面上进行了拆分,与线程相关的是抢占式多任务,与协程相关的是协作式多任务。

如果没有协程,当一个线程内遇到IO等待时,会切换到别的线程去执行,但是有了协程,一个线程内的某个子程序遇到IO等待时,会将控制权交给同在线程内的其他子程序,没有了线程之间的切换,没有了锁,效率自然变高了。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案