本指南的目的是解释为什么在Python中需要多线程和多处理,何时使用多线程和多处理,以及如何在程序中使用它们。

文章太长不想看?这里是内容摘要啦~

  • 对于IO-bound任务,使用多线程可以提高性能
  • 对于IO-bound任务,使用多进程也可以提高性能,但是开销往往比使用多线程要高
  • Python GIL意味着在Python程序的任意给定时间内只能执行线程
  • 对于CPU bound任务,使用多线程实际会降低性能
  • 对于CPU bound任务,使用多进程可以提高性能
  • 巫师真的很棒!


很久很久以前,在一个遥远的星系里……

一个聪明而强大的巫师住在一个偏僻的小村庄里。我们叫他邓布利多吧。他不仅聪明、有能力,而且乐于帮助任何请求帮助的人,这意味着人们从四面八方来请求巫师的帮助。我们的故事开始于一个晴朗的日子,一个年轻的旅行者给巫师带来了一卷魔法卷轴。旅行者不知道卷轴里装的是什么,但他知道,如果有人能破译出卷轴的秘密,那一定是伟大的巫师邓布利多。

单线程 单进程

如果你还没有猜出来我这个故事的内涵,其实我是在比喻关于CPU及其功能的。我们的巫师是CPU,而魔法卷轴是一个url列表,它可以引导Python的强大功能和使用该功能的知识。

巫师没费多大力气就破译了卷轴,他的第一个念头就是派他信任的朋友到卷轴上给出的每一个位置去看看并带回他能找到的东西。

如您所见,我们只是使用for循环一个接一个地遍历url并读取响应。多亏了从IPython获得的%%time的魔力,我们能够看到用这个糟糕的方法需要花费12秒。

多线程

巫师的智慧在这片土地上闻名遐迩,他很快就想出了一个更有效的方法。与其将一个人按顺序送到每个地点,不如召集一群(值得信任的)人,同时将他们分别发送到每个地点! 一旦他们都回来了,巫师就可以简单地把他们带回来的一切结合起来。

没错,我们可以使用多线程来同时访问多个url,而不是一个接一个地遍历列表。


这样就好多啦!使用多线程可以显著加快许多与 IO-bound的任务。在这里,读取 URLs 所花费的大部分时间是由于网络延迟。 IO-bound程序大部分时间都在等待输入和输出(您猜对了,类似于巫师需要等待他的朋友/朋友到卷轴中给定的位置并返回)。这可能是来自网络、数据库、文件甚至用户的I/O。这种I/O往往要花费大量的时间,因为源本身可能需要在传递I/O之前执行自己的处理。例如,CPU的工作速度比网络连接传输数据的速度快得多。
注意:多线程在网络数据抓取等任务中非常有用。

多进程

随着时间的流逝,我们巫师的名气越来越大,一个相当讨厌的黑巫师在嫉妒的驱使下,使用狡猾的手段对邓布利多下了一个可怕的咒语。咒语一解开,邓布利多就知道他只有片刻的时间可以打破它。绝望中,他翻遍了自己的咒语书,找到了一个似乎可以奏效的反咒。唯一的问题是,它要求他计算所有质数之和低于100万。

现在,巫师知道,如果有足够的时间,计算值将是微不足道的,但是时间并不是他所拥有的奢侈品。虽然他是一个巫师,但他也受到人性的限制,一次只能计算一个数字。如果是的话,要一个一个地把质数加起来,那就太费时间了。在还剩几秒钟的时候,他突然想起了多年前从魔法卷轴中学到的多重处理咒语。这个咒语可以让他复制自己,把这些数字分开,他就可以同时检查多个数字是否是质数。最后,他所要做的就是把他和他的副本发现的所有质数加起来。



由于现代CPU通常有多个核心,我们可以通过使用多进程模块来加快CPU绑定任务的速度。CPU绑定任务是花费大部分时间在CPU上执行计算的程序(数学计算、图像处理等)。如果计算可以彼此独立地执行,我们就可以将它们分配到可用的CPU内核中,从而显著提高处理速度。

你所要做的就是;

  1. 定义要应用的函数
  2. 准备要应用的函数列表
  3. 使用多进程池生成进程,传递给Pool()的数目将是派生进程的数目。嵌入with语句可以确保进程在执行完成后被终止。
  4. 使用进程池的map函数组合输出,map函数的输入是要应用于每个项目的函数和项目列表

注意:可以定义该函数,以便执行可以并行执行的任务。例如,函数可能包含将计算结果写入文件的代码


那么,为什么我们需要单独的多进程和多线程呢?如果你尝试使用多线程来提高CPU bound任务,你可能会注意到,实际得到的是性能下降。让我们看看为什么会这样。

就像巫师收到人性的限制,每次只能计算一个数字一样,Python也带有一种称为全局解释器锁(GIL)的东西。Python很乐意让你生成任意数量的线程,但GIL确保在任何给定时间只有一个线程可以执行。

对于IO-bound任务,这非常好。一个线程向URL发出请求,当他等待响应时,他可以将该线程替换为向另一个URL发出另一个请求的另一个线程。因为一个线程在收到响应之前不需要做任何事,所以在给定的时间内只执行一个线程并不重要。

对于CPU bound任务,多线程并没有什么用。因为一次只执行一个线程,即使生成多个线程,并且每个线程都有自己要检查的素数,CPU仍然一次只处理一个线程。实际上,这些数字仍然会被一个接一个的检查。如果在CPU bound 任务中使用多线程,那么处理多线程的开销将导致性能下降。


为了克服这个“限制”,我们使用了多进程模块。多进程不是使用线程,而是使用多个进程。每个进程都有自己的解释器和内存空间,因为GIL不会组织任何事情。本质上,每个进程使用不同的CPU内核同时处理不同的数字。

你可能会注意到,与使用简单的for循环,甚至是多线程相比,使用多进程处理时CPU利用率要高得多。这是因为你的程序使用多个CPU内核,而不仅仅是一个内核。这是个好事。

请记住,multiprocessing多处理本身就有管理多个进程的开销,这通常比多线程开销更大。(multiprocessing生成一个单独的解释器,并为每个进程分配一个单独的内存空间)这意味着,根据经验,当可以使用轻量级多线程时,最好使用它(io绑定任务)。当CPU处理成为瓶颈时,通常需要调用多处理模块。但请记住,能力越大,责任越大。

如果一次生成的进程超过CPU的处理能力,你将注意到性能开始下降。这是因为你的进程比内核多,操作系统现在必须做更多的工作来交换CPU内核内外的进程。实际情况可能比简单的解释要复杂的多,但这是基本思想。当我们到达16个进程时,你可以看到我的系统性能的下降。这是因为我的CPU只有16个逻辑内核。

以上就是对Python中多线程和多进程的介绍。感谢您的观看!
让我们勇往直前,征服一切叭!

Python效率之王之多进程和多线程详解相关推荐

  1. python可以开多少线程_python多线程详解

    python多线程详解 一.线程介绍 什么是线程 线程(Thread)也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位.线程自己不拥有系统资源,只拥有一 ...

  2. Python之多进程和多线程详解

    1.进程的概念 一个CPU的时候运行,轮询调度实现并发执行 多CPU运行机制: 计算机程序:存储在磁盘上的可执行二进制(或其他类型)文件. 只有把它们加载到内存中,并被操作系统调用它们才会拥有其自己的 ...

  3. 很多人现在还不知道的知识点,Python多进程和多线程详解!

    1 单进程单线程:一个人在一个桌子上吃菜. 2 单进程多线程:多个人在同一个桌子上一起吃菜. 3 多进程单线程:多个人每个人在自己的桌子上吃菜. 多线程的问题是多个人同时吃一道菜的时候容易发生争抢,例 ...

  4. python多线程详解 Python 垃圾回收机制

    文章目录 python多线程详解 一.线程介绍 什么是线程 为什么要使用多线程 总结起来,使用多线程编程具有如下几个优点: 二.线程实现 自定义线程 守护线程 主线程等待子线程结束 多线程共享全局变量 ...

  5. python多进程应用场景_python使用多进程的实例详解

    python多线程适合IO密集型场景,而在CPU密集型场景,并不能充分利用多核CPU,而协程本质基于线程,同样不能充分发挥多核的优势. 针对计算密集型场景需要使用多进程,python的multipro ...

  6. python多进程队列中的队列_python 多进程队列数据处理详解

    我就废话不多说了,直接上代码吧! # -*- coding:utf8 -*- import paho.mqtt.client as mqtt from multiprocessing import P ...

  7. [Python 多线程] 详解daemon属性值None,False,True的区别

    [Python 多线程] 详解daemon属性值None,False,True的区别 记录学习python不懂得和遇到得问题 每个进程至少要有一个线程,并最为程序的入口,这个进程就是主线程. 每个进程 ...

  8. python协程详解_对Python协程之异步同步的区别详解

    一下代码通过协程.多线程.多进程的方式,运行代码展示异步与同步的区别. import gevent import threading import multiprocessing # 这里展示同步和异 ...

  9. python gil 解除_详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案

    先看一道GIL面试题: 描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因. GIL:又叫全局解 ...

  10. python小游戏代码大全-20行python代码的入门级小游戏的详解

    背景: 作为一个python小白,今天从菜鸟教程上看了一些python的教程,看到了python的一些语法,对比起来(有其他语言功底),感觉还是非常有趣,就随手添了一点内容,改了一个小例程,当着练练手 ...

最新文章

  1. 点击切换属性html,jQuery_$方法、属性、点击切换
  2. MySql安装后在服务管理器里边找不到MySql服务项的解决办法(win10)
  3. 使用fastcoll进行md5碰撞,两个不同的文件md5值一样。
  4. Leetcode--560. 和为K的子数组
  5. 用Response.Filter生成静态页
  6. 链表插入排序和冒泡排序c语言
  7. RemoteFX+RDP8.0+hyper-v重定向智能卡,U盾问题
  8. 如何理解UEFI的事件机制(三)——时钟中断
  9. (计算圓柱体的体积)编写程序,读入圆柱体的半径和高,并使用下列公式计算圆柱的体积
  10. cass等距离等分线段的命令键_教你用CAD将线段等分,弧线也可定距等分!
  11. 虚拟机建Mac系统步骤
  12. 「自动搬运+CDN」FFmpeg + x264 t_mod + x265 yuuki
  13. 2021-07-16 转载 - UmiJS应用框架
  14. 缺氧游戏黑科技计算机,《缺氧》怎么生存?缺氧bug黑科技小技巧使用方法一览...
  15. 掌握生成对抗网络(GANs),召唤专属二次元老婆(老公)不是梦
  16. 大麦票夹:从工具到服务的技术演进之路
  17. 【大学课程自学网站】
  18. 虾皮API接口—获取商品详情
  19. 电力通信专业技术总结,智能电网通信技术总结
  20. rails网站开发所使用的插件收集---web开发工具集

热门文章

  1. 本地连接服务器无响应怎么解决办法,本地连接的服务器未响应
  2. 解决没有配置本地nacos但是一直发生localhost8848连接异常的问题
  3. 柔宇科技奔赴上市为哪般?自称“销售规模较小”,合计亏超30亿
  4. 10个提供Logo设计灵感的创意网站
  5. tp6 的unique验证
  6. oracle lob函数,Oracle可以处理LOB字段的常用字符函数
  7. php 调用 com组件,进行word操作,详情步骤
  8. 开发板连接了有线路由器,然后咋的就能通到外网了(udhcp)
  9. 社群裂变工具有哪些?裂变活动成功的4个关键点!
  10. Spring注解开发