【Python】Python多任务第1篇:多进程、多线程与协程通俗易懂的理解方式

本期任务:介绍Python的多任务及其实现范例

【Python】Python多任务第1篇:多进程、多线程与协程通俗易懂的理解方式

【Python】Python多任务第2篇:多线程、多进程与协程的代码实现范例

完整GitHub代码:MultiTasking


面试和实际应用中,往往需要与多任务打交道,但是对于多任务,你真的理解到位了吗?本文将分享多进程、多线程与协程通俗易懂的理解方式,希望能对你有帮助。


一、剪刀厂模型(感性认识)

设想这么一个情境,有一个老板想要开个工厂进行生产某件商品(例如剪刀)

  • 他需要花一些财力物力制作一条生产线,这个生产线上有许多的器件以及材料,这些为了能够生产剪刀而准备的资源称之为:进程
  • 只有生产线是不能够进行生产的,所以老板要找个工人来进行生产,这个工人能够利用这些材料最终一步步的将剪刀做出来,这个来做事情的工人称之为,即:线程
  • 这个老板为了提高生产率,想到三个办法:
    • 在这条生产线上多找一些工人,一起来做剪刀:单进程、多线程方式
    • 老板发现这条生产线上的工人不是越多越好,因为一条生产线的资源以及材料毕竟有限,所以老板又花了一些财力物力购置了另外一条生产线,然后在招一些工人,这样效率又再一步提高了,即:多进程、多线程方式。
    • 老板发现,现在已经有了很多条生产线,并且每条生产线上已经有了很多工人(即程序是多进程的,每个进程又有多个线程),为了再次提高效率,老板想了一个"损招",规定:如果某个工人在上班时临时没事或者等待某些条件(比如等待另一个工人生产完成某道工序之后,他才能再次工作),那么这个员工就利用这个时间去做其他的事情,那么也就是说:如果一个线程等待某些条件,可以充分利用这个时间去做其他事情,其实这就是:协程方式。

简单总结

  1. 进程是资源分配的单位 (“生产线”)
  2. 线程是操作系统调度的单位(真正干活的是"工人")
  3. 进程切换需要的资源最大,效率很低
  4. 线程切换需要的资源一般、效率一般(不考虑GIL的情况)
  5. 协程切换任务的资源很小,效率很高
  6. 多进程、多线程根据CPU核数不一样可能是并行的,但是协程是在一个线程中,所以是并发

二、多任务相关

  1. 什么是多任务?
    简单地说,就是操作系统可以同时执行多个任务;在代码里面,就是一个程序有多个地方同时执行,打个比方,你一边用着这浏览器上网,一边在听MP3,一边在用Word赶作业,这就是多任务。

  2. 单核CPU是怎么解决多任务的?
    单核:意味着同一时刻只能执行一件事情;操作系统轮流让各任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01,再切换到任务3,执行0.01秒。。。这样反复的执行下去,每个任务都是交替执行的,但是由于CPU的执行速度实在是太快了,我们感觉就像是所有任务都在同时执行一样,这就是所谓的 “时间片轮转” 。

  3. 并行和并发
    并行: 真的多任务 (CPU的核数大于任务数量);并发: 假的多任务 (CPU的核数小于任务数量)。真正的并行执行多任务只能在多核CPU上实现,但是,由于任务数量远远多于CPU的核心数量,所以,操作系统也会自动 把很多任务轮流调度到每个核心上执行。


三、进程、线程再对比

  • 功能
    • 进程:能够完成多任务,比如在一台电脑上能够同时运行多个QQ
    • 线程:能够完成多任务,比如在一个QQ中的多个聊天窗口
  • 定义
    • 进程是系统进行资源分配和调度的一个独立单元
    • 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能够独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈)。但是它可与同属于一个进程的其它的线程共享所拥有的全部资源。
  • 区别
    • 一个程序至少由一个进程,一个进程至少有一个线程。
    • 线程的划分尺度小于进程(资源比进程少), 使得多线程程序的并发性高。
    • 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
    • 线程不能独立执行,必须依存在进程中。
    • 可以将进程理解为工厂中的一条流水线,而其中的线程就是这个流水线上的工人。
    • 线程执行开销小,但不利于资源的管理和保护;而进程则相反,且由于多进程之间彼此独立,使得进程之间的通信较为复杂。

四、协程再认识

协程(coroutine)顾名思义就是“协作的例程”(co-operative routines)。跟具有操作系统概念的线程不一样,协程是在用户空间利用程序语言的语法语义就能实现逻辑上类似多任务的编程技巧。实际上协程的概念比线程还要早,按照 Knuth 的说法“子例程是协程的特例”,一个子例程就是一次子函数调用,那么实际上协程就是类函数一样的程序组件,你可以在一个线程里面轻松创建数十万个协程,就像数十万次函数调用一样。只不过子例程只有一个调用入口起始点,返回之后就结束了,而协程入口既可以是起始点,又可以从上一个返回点继续执行,也就是说协程之间可以通过 yield 方式转移执行权,对称(symmetric)、平级地调用对方,而不是像例程那样上下级调用关系。

  • 进程、线程对比

    • 协程(coroutine),又称微线程,是一种用户态的轻量级线程。
    • 线程是系统级别的,由操作系统切换CPU进行调度。
    • 协程是程序级别的,由程序根据自己的需要调度。
  • 协程的优势:

    • 最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。
    • 第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。

未完待续。。。

本节介绍了Python多任务的相关问题,包括多进程、多线程与协程等概念,并对于它们之间的关系进行了总结。
下一节将介绍在Python中实现多线程、多进程与协程的范例。

【Python】Python多任务第2篇:多线程、多进程与协程的代码实现范例

参考
https://blog.csdn.net/qq_41333844/article/details/87259956
https://blog.csdn.net/u010487568/article/details/56841031
https://www.bilibili.com/video/BV19x411R7rG

原创文章 36 获赞 32 访问量 2750

猜你喜欢

转载自blog.csdn.net/weixin_43868754/article/details/105188918