线程和多处理模块之间有什么区别?

2024-03-19

我正在学习如何使用threadingmultiprocessingPython 中的模块可并行运行某些操作并加速我的代码。

我发现这很难(也许是因为我没有任何理论背景)来理解threading.Thread()对象和一个multiprocessing.Process() one.

另外,我并不完全清楚如何实例化一个作业队列,并让其中只有 4 个(例如)作业并行运行,而另一个则在执行之前等待资源释放。

我发现文档中的示例很清楚,但不是很详尽;一旦我尝试使事情变得复杂一点,我就会收到很多奇怪的错误(例如无法腌制的方法等等)。

那么,我什么时候应该使用threading and multiprocessing模块?

您能给我链接一些资源来解释这两个模块背后的概念以及如何正确使用它们来完成复杂的任务吗?


朱利奥·佛朗哥怎么说 https://stackoverflow.com/a/18114475对于多线程与多处理来说是正确的一般来说.

However, Python* has an added issue: There's a Global Interpreter Lock that prevents two threads in the same process from running Python code at the same time. This means that if you have 8 cores, and change your code to use 8 threads, it won't be able to use 800% CPU and run 8x faster; it'll use the same 100% CPU and run at the same speed. (In reality, it'll run a little slower, because there's extra overhead from threading, even if you don't have any shared data, but ignore that for now.)

但也有例外。如果您的代码的繁重计算实际上并未发生在 Python 中,而是在某些具有执行正确 GIL 处理的自定义 C 代码的库中(例如 numpy 应用程序),您将从线程中获得预期的性能优势。如果繁重的计算是由您运行并等待的某个子进程完成的,情况也是如此。

更重要的是,在某些情况下这并不重要。例如,网络服务器花费大部分时间从网络读取数据包,而 GUI 应用程序花费大部分时间等待用户事件。在网络服务器或 GUI 应用程序中使用线程的原因之一是允许您执行长时间运行的“后台任务”,而无需停止主线程继续服务网络数据包或 GUI 事件。这对于 Python 线程来说效果很好。 (用技术术语来说,这意味着 Python 线程为您提供并发性,即使它们不为您提供核心并行性。)

但是,如果您用纯 Python 编写 CPU 密集型程序,那么使用更多线程通常没有帮助。

使用单独的进程就没有GIL这样的问题,因为每个进程都有自己单独的GIL。当然,与任何其他语言一样,您仍然需要在线程和进程之间进行权衡 - 在进程之间共享数据比在线程之间共享数据更困难且更昂贵,运行大量进程或创建和销毁进程的成本可能会很高但 GIL 严重影响了进程的平衡,而对于 C 或 Java 来说,情况并非如此。因此,您会发现自己在 Python 中比在 C 或 Java 中更频繁地使用多处理。


与此同时,Python 的“自带电池”哲学带来了一些好消息:编写可以通过一行更改在线程和进程之间来回切换的代码非常容易。

如果您根据独立的“作业”设计代码,除了输入和输出之外,不与其他作业(或主程序)共享任何内容,则可以使用concurrent.futures http://docs.python.org/3/library/concurrent.futures.html围绕线程池编写代码的库,如下所示:

with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
    executor.submit(job, argument)
    executor.map(some_function, collection_of_independent_things)
    # ...

您甚至可以获取这些作业的结果并将其传递给进一步的作业,按执行顺序或完成顺序等待事物等;阅读有关的部分Future对象以获取详细信息。

现在,如果事实证明您的程序不断使用 100% CPU,并且添加更多线程只会使其速度变慢,那么您就会遇到 GIL 问题,因此您需要切换到进程。您所要做的就是更改第一行:

with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:

唯一真正需要注意的是,作业的参数和返回值必须是可腌制的(并且不会花费太多时间或内存来腌制)才能跨进程使用。通常这不是问题,但有时却是问题。


但如果您的工作不能独立怎么办?如果您可以根据工作来设计代码传递消息从一个到另一个,仍然很容易。你可能需要使用threading.Thread or multiprocessing.Process而不是依赖池。你必须创建queue.Queue or multiprocessing.Queue明确对象。 (还有很多其他选项——管道、套接字、带有羊群的文件……但重点是,你必须这样做某物如果执行器的自动魔法不够,则手动进行。)

但是如果您甚至不能依赖消息传递怎么办?如果您需要两项工作来改变相同的结构并查看彼此的变化怎么办?在这种情况下,您将需要进行手动同步(锁、信号量、条件等),并且如果您想使用进程,还需要显式共享内存对象来启动。这是多线程(或多处理)变得困难的时候。如果你能避免它,那就太好了;如果你不能,你将需要阅读比某人可以放入 SO 答案更多的内容。


从评论中,您想了解 Python 中线程和进程之间的区别。真的,如果您阅读朱利奥·佛朗哥的答案和我的答案以及我们所有的链接,那应该涵盖所有内容……但是摘要肯定会很有用,所以这里是:

  1. 线程默认共享数据;进程则不然。
  2. As a consequence of (1), sending data between processes generally requires pickling and unpickling it.**
  3. 作为(1)的另一个结果,在进程之间直接共享数据通常需要将其放入低级格式,如值、数组和ctypes types.
  4. 进程不受 GIL 的约束。
  5. 在某些平台(主要是 Windows)上,创建和销毁进程的成本要高得多。
  6. 进程有一些额外的限制,其中一些在不同平台上是不同的。看编程指南 http://docs.python.org/3/library/multiprocessing.html#multiprocessing-programming了解详情。
  7. The threading模块不具备某些功能multiprocessing模块。 (您可以使用multiprocessing.dummy要在线程之上获取大部分缺失的 API,或者您可以使用更高级别的模块,例如concurrent.futures不用担心。)

* It's not actually Python, the language, that has this issue, but CPython, the "standard" implementation of that language. Some other implementations don't have a GIL, like Jython.

** If you're using the fork https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods start method for multiprocessing—which you can on most non-Windows platforms—each child process gets any resources the parent had when the child was started, which can be another way to pass data to children.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

线程和多处理模块之间有什么区别? 的相关文章

  • 如何在cvxpy中编写多个约束?

    我想在 cvxpy 下的优化问题中添加许多约束 在 matlab 中 我可以通过添加一行 subject to 然后使用 for 循环来生成约束 我怎样才能在 cvxpy 中做同样的工作 因为 cvxpy 中没有 服从 概念 有什么建议吗
  • Python:如何删除圆括号内的文本?

    我试过了 但没用 return re sub myResultStats text 建议 thanks 尝试这个 return re sub myResultStats text 括号表示捕获组 因此您必须转义它们
  • 从 SQL Server 中调用 Python 文件

    我的文件名中有 Python 脚本 C Python HL py 在此 Python 脚本中 有预测模型以及对 SQL 数据库中某些表的更新 我想将此文件称为 SQL 作业 我怎样才能做到这一点 这个问题不一样 如何在 SQL Server
  • 通过 pyodbc 连接到 Azure SQL 数据库

    我使用 pyodbc 连接到本地 SQL 数据库 该数据库工作正常 SQLSERVERLOCAL Driver SQL Server Native Client 11 0 Server localdb v11 0 integrated se
  • 这是我尝试安装 pip3 时得到的结果

    这是我尝试安装 pip3 时得到的结果 sudo apt get install python3 pip Reading package lists Done Building dependency tree Reading state i
  • python: X 服务器上的致命 IO 错误 11(资源暂时不可用):0.0

    我正在尝试读取一些图像 稍后打算对它们执行一些任务 同时将图像读入内存 我想显示动画 gif 图像 为此 我必须使用线程 现在它给出错误 python Fatal IO error 11 Resource temporarily unava
  • 使用python同时播放两个正弦音

    我正在使用 python 来播放正弦音 音调基于计算机的内部时间 以分钟为单位 但我想根据秒同时播放一个音调 以获得和谐或双重的声音 这就是我到目前为止所拥有的 有人能指出我正确的方向吗 from struct import pack fr
  • VSCode Jupyter Notebook - 恢复缓存版本

    我正在使用在 Ubuntu 19 10 上运行的 VSCode v 1 48 0 创建一个 Jupyter Notebook VSCode 崩溃了 不幸的是我没有保存笔记本 当我重新启动时它是空的 我已经能够在 config Code Us
  • 导入错误:无法导入名称 urandom

    我正在构建一个新的 Linux 环境 并在 Python 上看到以下错误 python c import random Traceback most recent call last File
  • python中remove方法的安全使用

    我从列表继承了一个 UserList 类并实现了以下方法来删除标记为已删除的条目 def purge deleted self for element in list iter self if ele mark deleted lt 1 s
  • 如何将 Jinja 与 Twisted 一起使用?

    我正在计划使用 Python 与 Twisted Storm 和 Jinja 一起开发一个讨论软件 问题是 Jinja 不是为 Twisted 或异步套接字库而设计的 并且使用 Twisted 提供的性能是我不打算使用 Flask 的原因
  • “分页文件太小,无法完成此操作”尝试训练 YOLOv5 对象检测模型时出错

    我有大约 50000 个图像和注释文件用于训练 YOLOv5 对象检测模型 我在另一台计算机上仅使用 CPU 训练模型没有问题 但需要太长时间 因此我需要 GPU 训练 我的问题是 当我尝试使用 GPU 进行训练时 我不断收到此错误 OSE
  • captureWarnings 设置为 True 不会捕获警告

    我想记录所有警告 我以为这样的设定captureWarnings to True应该可以解决问题 但事实并非如此 代码 import logging import warnings from logging handlers import
  • pip:证书失败,但curl 有效

    我们在客户端安装了根证书 https 连接适用于curl 但如果我们尝试使用pip 它失败 Could not fetch URL https installserver 40443 pypi simple pep8 There was a
  • 如何克服 numpy.unique 的 MemoryError

    我正在使用 Numpy 版本 1 11 1 并且必须处理一个二维数组 my arr shape 25000 25000 所有值都是整数 我需要一个唯一的数组值列表 使用时lst np unique my arr 我正进入 状态 Traceb
  • 在Python中计算矩阵乘以其转置(AA^T)的最快方法

    在Python中将矩阵与其转置 AA T 相乘的最快方法是什么 我认为 NumPy SciPy 没有考虑使用例如时涉及的对称性 np dot or np matmul 得到的矩阵总是对称的 所以我可以想象有一个更快的解决方案 None
  • 使用 JSON 可序列化枚举自动生成棉花糖模式

    创建与我的模型相同的棉花糖模式的日子已经一去不复返了 我发现这个优秀的答案 https stackoverflow com a 42892443 4097322这解释了我如何使用简单的装饰器从 SQA 模型自动生成模式 因此我实现了它并替换
  • 张量流多元线性回归不收敛

    我正在尝试使用张量流训练具有正则化的多元线性回归模型 由于某种原因 我无法获取以下代码的训练部分来计算我想要用于梯度下降更新的误差 我在设置图表时做错了什么吗 def normalize data matrix averages np av
  • 如何访问模板缓存? - 姜戈

    I am 缓存 HTML在几个模板内 例如 cache 900 stats stats endcache 我可以使用以下方式访问缓存吗低级图书馆 例如 html cache get stats 我确实需要对模板缓存进行一些细粒度的控制 有任
  • 用于获取有关 SVN 存储库信息的 Python 库?

    我正在寻找一个可以从 SVN 存储库中提取 至少 以下信息的库 not工作副本 修订号及其作者和提交消息 每个修订版中的更改 添加 删除 修改文件 有Python库可以做到这一点吗 对于作者和提交消息 我可以解析 db revprops 0

随机推荐