Justin-刘清政的博客

2-进程线程与协程

2020-03-25

1 进程

进程是具有一定独立功能的程序、它是系统进行资源分配和调度的一个独立单位,重点在系统调度和单独的单位,也就是说进程是可以独 立运行的一段程序

2 线程

线程是进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源。在运行时,只是暂用一些计数器、寄存器和栈 。

  1. 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程(通常说的主线程)。
  2. 资源分配给进程,同一进程的所有线程共享该进程的所有资源。
  3. 线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
  4. 处理机分给线程,即真正在处理机上运行的是线程。
  5. 线程是指进程内的一个执行单元,也是进程内的可调度实体。
image-20200325230936014

3 协程

程序中任务执行的本质是CPU作为执行者运行代码,因此并行必定意味着多核,并发好比单核切换交替执行多个任务。

由于Python解释器中GIL全局解释器锁的问题,Python的多线程只能实现并发,多进程才能实现并行。而协程是在单线程中实现的,因此协程也只能实现并发。

协程又被称为微线程,是抽象出来的一个概念;而进程和线程都是实际存在的对象,是操作系统中确确实实存在的东西。

因而多进程、多线程的切换是操作系统负责的,而协程的切换不是由操作系统的。

也就是说只要是单线程中实现了多个任务的交替/切换的执行,那么它就是协程。同时协程的切换本质上由用户控制。

协程的实现方式

image-20200325231206907

协程的实现方式其实都是通过将CPU的执行环境(控制单元、存储单元、运算单元)进行替换实现的。因为CPU只根据它控制单元、存储单元、运算单元里的东西来运算。

如当前CPU正在运行函数1,那么此时直接将函数1在CPU的运行情况保存起来,然后替换成函数2的,这样就实现了从函数1到函数2的切换。

具体实现一般分为两种情况:

  • 一种是语言特性,原生支持,如Python的yield、Go的goroutine等;
  • 另一种是第三方模块的单独实现,如gevent中的使用的greenlet。

IO密集任务与计算密集任务

  • IO密集型:适合多线程或协程
    • 大量磁盘I/O操作(文件读写、磁盘读写)
    • 大量网络I/O操作(网络请求、socket程序)
  • 计算密集型:适合多进程
    • 大量运算操作(计算精确到小数点1000位的圆周率、视频高清解码、图像运算)
    • 大量逻辑判断操作(循环判断、if判断等大量逻辑代码处理)
  • 原因:
    • I/O操作不会占用CPU,多线程、协程能同时处理多个I/O操作
    • 计算操作需要一直使用CPU,多进程能利用多个核心
    • 多进程资源开销比多线程资源开销大很多

网络应用是I/O密集型应用,爬虫程序是I/O密集型应用。

而显然针对I/O密集型程序,协程开销相较于线程小得多

Tags: Python
使用支付宝打赏
使用微信打赏

点击上方按钮,请我喝杯咖啡!

扫描二维码,分享此文章