热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python并发编程_用Python进行并发编程不是您想的那样。

python并发编程最初发布于melvinkoh.me在本文中,我将首先带您了解并发编程与并行执行之间的区别,讨论有关Python内置的并发编程机制以及

python 并发编程

最初发布于 melvinkoh.me

在本文中,我将首先带您了解并发编程与并行执行之间的区别,讨论有关Python内置的并发编程机制以及Python中多线程的陷阱。

了解并发编程与并行执行

尽管事实上这两个术语经常互换使用,但并发编程并不等同于并行执行。

>没有并行的并发插图

并发是一个属性,可以同时运行多个操作,但这并不意味着可以并发。 (想象一下,如果您的处理器是单线程的。)

>并行性插图

并行是实际上同时运行操作的属性。 通常由硬件限制决定。

将您的程序视为一条快餐链,当构建两个单独的订单和收款柜台时,并发即被合并。 但是,它不能确保并行性,因为它取决于可用雇员的数量。 如果只有一名员工同时处理订单和收款请求,则这些操作不能并行运行。 仅当有两个员工同时服务于订单和收货时,才出现并行。

Python内置

现在,我们在Python中拥有什么? Python是否有内置程序可以帮助我们构建并发程序并使它们并行运行?

在下面的讨论中,我们假定我们的程序都是在多线程或多核处理器中编写并运行的。

答案是Jein (德语为是和否)。 为什么是? Python确实具有用于最常见的并发编程结构(多处理和多线程)的内置库。 您可能会认为,由于Python同时支持,为什么选择Jein? 原因是,由于Python中的GIL,Python中的多线程并不是真正的多线程。

多线程—基于线程的并行性

threading是提供用于创建和管理线程的API的软件包。 Python中的线程始终是不确定性的,它们的调度由操作系统执行。 但是,多线程可能无法达到您的预期。

为什么Python中的多线程可能不是您想要的?

除了常见的陷阱(如死锁)之外,多线程通常会出现饥饿。 Python因其在多线程中的性能较差而臭名昭著。

让我们看一下以下代码片段:

import threadingdef countdown () :x = 1000000000while x > 0 :x -= 1
# Implementation 1: Multi-threading
def implementation_1 () :thread_1 = threading.Thread(target=countdown)thread_2 = threading.Thread(target=countdown)thread_1.start()thread_2.start()thread_1.join()thread_2.join()
# Implementation 2: Run in serial
def implementation_2 () :countdown()countdown()

哪个实施会更快? 让我们执行一个定时。

>两种实现的时序结果

令人惊讶的是,连续运行2个countdown()胜过多线程吗? 这怎么可能呢? 多亏了臭名昭著的Global Interpreter Lock(GIL)。

什么是全局翻译锁定(GIL)?

在大多数情况下,取决于Python的分布是CPython的实现。 CPython是Python的原始实现,您可以在此StackOverflow线程中阅读有关它的更多信息。

在CPython中,通过引入称为全局解释器锁(又称为GIL)的互斥对象来支持多线程。 这是为了防止多个线程同时访问同一Python对象。 这是有道理的,您不希望其他人在处理对象时对其进行变异。

>实施示意图_1

因此,从上面的代码段中, implementation_1创建2个线程,并应在多线程系统上并行运行。 但是,一次只能有一个线程可以容纳GIL,一个线程必须等待另一线程释放GIL才能运行。 同时,由操作系统完成的调度和切换会带来开销,从而使implementation_1变得更加缓慢。

如何绕过GIL?

我们如何在保持多线程使用的同时绕过GIL? 这个问题没有通用的好答案,因为这与您的代码目的有所不同。

可以选择使用Jython,PyPy或IronPython等不同的Python实现。 我个人不主张使用不同的Python实现,因为大多数编写的库都没有针对不同的Python实现进行测试。

另一个可能的解决方法是使用C扩展,或更好地称为Cython 。 请注意,Cython和CPython是不同的。 您可以在此处阅读有关Cython的更多信息。

请改用多处理。 由于在多处理中,将为每个子进程创建一个解释器。 不存在争用GIL简单线程的情况,因为在每个进程中始终只有一个主线程。

尽管存在所有陷阱,我们是否仍应使用多线程?

如果您的任务是受I / O约束的,则意味着线程将花费大部分时间来处理I / O,例如执行网络请求。 仍然可以使用多线程,因为在大多数情况下,线程被操作系统阻塞并放入阻塞队列中。 线程也总是比进程少耗费资源。

多处理—基于过程的并行性

让我们使用多重处理实现我们之前的代码片段。

import multiprocessing
# countdown() is defined in the previous snippet.
def implementation_3 () :process_1 = multiprocessing.Process(target=countdown)process_2 = multiprocessing.Process(target=countdown)process_1.start()process_2.start()process_1.join()process_2.join()

结果本身是不言自明的。

>多处理与多线程的计时结果

结论

GIL的约束在最初作为Python开发人员时吸引了我。 直到我确定时机,我才意识到使用线程的决定是毫无价值的。 希望本文对您有所帮助。

翻译自: https://hackernoon.com/concurrent-programming-in-python-is-not-what-you-think-it-is-b6439c3f3e6a

python 并发编程



推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了在使用Python中的aiohttp模块模拟服务器时出现的连接失败问题,并提供了相应的解决方法。文章中详细说明了出错的代码以及相关的软件版本和环境信息,同时也提到了相关的警告信息和函数的替代方案。通过阅读本文,读者可以了解到如何解决Python连接服务器失败的问题,并对aiohttp模块有更深入的了解。 ... [详细]
author-avatar
永城之家_319
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有