
编辑推荐:
本文来自python社区. 本文主要介绍Python的并发多线程和多进程,并举例说明如何使用多线程并发下载图片,以及如何使用多进程执行数值运算. 希望对您的学习有所帮助.
本文摘要
1. 线程和多线程
2. 处理和多处理
3. 多线程同时下载图片
4. 多进程并发改善了数字操作
关于并发
在计算机编程领域,并发编程是一个非常普遍的术语和功能. 实际上,并发的概念最初起源于铁路和电报的早期工作. 例如,如何在同一铁路系统上安排多列火车,以确保每列火车的运行不会冲突.
1960年代后期,学术界开始研究计算机的并行计算. 后来,操作系统能够执行并发处理任务,并且编程语言能够为程序实现并发功能.
线程和多线程
什么是线程
线程可以看作是有序的指令流(完成特定任务的指令),并且这些指令流可以由操作系统调度.
线程通常位于进程中,由程序计数器,堆栈,一组寄存器和一个标识符组成. 这些线程是处理器可以分配时间的最小执行单元.
线程可以共享内存并相互通信. 但是,当两个线程开始共享内存时python多进程效率,无法保证线程执行的顺序,这可能导致程序错误或产生错误的结果. 以后我们会特别提到这个问题.
下图显示了多个CPU中如何存在多个线程:

线程类型
在典型的操作系统中,通常有两种类型的线程:
1. 用户级线程: 我们可以创建,运行和杀死的线程;
2. 内核级线程: 操作系统运行的低级线程;
Python在用户级线程上运行,我们介绍的内容主要在用户级线程上运行.

什么是多线程
当前的CPU基本上是多线程CPU. 例如,我们从JD.com中随机找到一个Inter Core i5处理器,并查看其产品规格:

这些CPU可以同时运行多个线程来处理任务. 实际上,这些CPU使用单个内核,可以在多个线程之间快速切换以完成多线程操作,并且可以快速切换线程的速度,因此我们感觉不到. 但从本质上讲,它们不能同时运行.
为了生动地理解多线程,让我们回顾一个场景.
在大学时期,学期末,一些学科教师将考试设置为公开考试,以免使每个人都感到尴尬. 我不知道面对开卷考试应该做什么顺序的问题?
在单线程工作模式下,我们编写多项选择题,填空题,简答题,然后依次分析问题.
当我们遇到一个特别困难的问题时,我们必须仔细阅读本书. 当然,由于这是一项开卷考试,因此某些问题的答案不能直接出现在教科书中,因此我们不得不花更多的时间寻找它. 答案是直到考试结束,因为一定的问题会消耗掉翻书的时间太多了,这使它无用做一些简单的问题. 好吧,当我打开书时,我无法完成试卷的编写,我会给你考试的地方.
在多线程工作模式下,我们也按顺序编写,但是遇到问题时,我们会在书中寻找一些答案. 如果找不到,我们将先做以下问题,然后做一些可以做的事情,先做一个简单的问题,然后再回到困难的问题,仔细地从下面的线索中寻找答案. 书.
在此示例中,我们仅单独执行此操作. 如果我们想更快地完成考试,我们必须与其他学生合作并分担工作.
让我们看一下线程的一些优点:
1. 多线程可以有效地提高I / O阻塞程序的效率;
2. 与该过程相比,它占用的系统资源更少;
3. 可以程之间共享资源以促进通信;
线程有一些缺点:
1. Python中有全局解释器锁(GIL)限制;
2. 尽管线程可以通信,但很容易在程序结果中引起错误. 使用它们时必须小心;
3. 在多个线程之间切换的计算成本很高,这将导致程序的整体性能下降.
流程和多流程
进程本质上与线程非常相似. 进程几乎可以执行线程可以执行的任何操作.
根据上述公开考试的示例,如果我们与室友组成一个小组,那么我们有四个CPU(4个人),并且有4个人编写并找到不同的答案. 这样可以大大提高考试效率.
在一个进程中,有一个主线程,并且可以生成许多子线程. 每个线程包含其自己的寄存器组合堆栈. 如有必要,它们可以由多个线程组成.
以下是单线程单进程和多线程单进程的示例:

流程特征
一个进程通常包含以下内容:
1. 进程ID,进程组ID,用户ID,组ID
2. 环境
3. 工作目录
4. 程序说明
5. 注册
6. 堆叠
7. 文件说明
8. 进程间通讯工具
9. 等等...
该过程具有以下优点:
1. 更好地利用多核处理器;
2. 处理CPU密集型任务时,它比多线程更好;
3. 可以使用多进程来避免全局解释器锁定(GIL)的限制;
4. 崩溃的进程不会导致整个程序崩溃;
同时,存在以下缺点:
1. 进程之间没有共享资源;
2. 该过程需要消耗更多的内存;
多进程
在Python中,我们可以使用多线程或多进程来运行我们的代码,以提高传统单线程方法的性能.
多线程可用于提高单核CPU的处理能力. 但是,在当前的计算机CPU中,多核处理器早已流行. 为了有效地利用机器的资源,必须使用多个过程来发挥机器的价值.
一个CPU内核将任务分配给其他CPU:

通过Python的进程处理模块多处理,我们可以有效地使用计算机上的所有处理器,这有助于我们在处理CPU密集型任务时获得更高的性能.
使用多处理模块检查计算机上的CPU内核数:

结果返回一个数字,即CPU内核数.
多进程不仅可以提高计算机的利用率,而且可以避免全局解释器锁的限制. 一个潜在的缺点是多个进程无法共享和通信(可以通过其他方式实现),但是这个缺点也使得多个进程更易于使用并避免崩溃.
Python的局限性
在本文之前,我们讨论了Python中全局解释器锁GIL的局限性. 那么GIL到底是什么?
GIL本质上是一个互斥锁,可以防止多个线程同时执行Python代码. 这是只能由一个线程持有的锁. 如果要线程执行代码,则必须先获得此锁,然后才能执行代码. 这样做的一个好处是,当它被锁定时,没有其他进程可以同时运行代码,从而在一定程度上避免了线程之间的冲突:

上图说明了GIL如何阻止多个线程. 在继续下一步之前,每个线程必须等待获取GIL,然后释放GIL. 线程之间使用随机循环,因此无法控制和保证哪个线程将首先获得GIL.
这种设计似乎非常反人类,这是许批评Python的地方. 但是,这种设计确实可以确保多个线程之间的内存安全.
现在我们已经了解了线程和进程以及Python的一些局限性,是时候了解如何在应用程序中使用多线程和多进程来提高程序速度了.
并发文件下载
毫无疑问,多线程优势的一个示例是使用多线程下载多个图像或文件. 由于I / O具有阻塞性,因此下载任务可能是多线程的最佳应用程序场景.
这是一个文本文件,提供了2017年的所有假期:

我们访问了10次,获得了10个文本文件,然后将其保存在本地.
首先查看常见的爬网:


我们介绍了模块urllib.request,然后创建了一个函数downloadImage()来下载文件,并创建了一个函数main()来遍历下载函数20次.

花了4秒钟以上.
让我们看一下多线程的使用:

程序的第一部分几乎相同. 稍后,我们创建一个线程列表,然后遍历10次python多进程效率,创建一个新的线程对象,将其添加到线程列表中,然后启动该线程.
最后,我们通过遍历线程列表来调用线程,然后在每个线程上调用join()方法,以确保在下载文件之前我们不会执行其余代码.

运行代码,您会发现程序几乎同时启动了10个下载任务,然后在图片下载后将其打印出来.
花了0.1秒,效率大大提高了.
但是,应该注意的是,对于网络上的文件IO,还需要考虑网络条件和您自己计算机的影响. 在不同的网络条件下,完成效率是不同的.
并行数字操作
I / O密集型任务适用于多线程,而CPU密集型任务适用于多进程.
在下面的示例中,我们将找到100万个质数,其中随机数在20000至100000000之间.
顺序操作:


花了18秒.
多进程计算:


花了11秒.
我们分别使用多进程处理池依次循环了100万次和100万次. 多进程模式下的速度提高了近7秒.
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-288255-1.html
好官方的分析
怎么想出这注意的
美国提供了什么帮助