python - Python 多处理 - 如何使其更高效
问题描述
考虑以下两个短程序。
normal_test.py:
import time
if __name__ == '__main__':
t_end = time.time() + 1
loop_iterations = 0
while time.time() < t_end:
loop_iterations += 1
print(loop_iterations)
输出(在我的机器上):
4900677
mp_test.py:
from multiprocessing import Process
from multiprocessing import Manager
import time
def loop1(ns):
t_end = time.time() + 1
while time.time() < t_end:
ns.loop_iterations1 += 1
def loop2(ns):
t_end = time.time() + 1
while time.time() < t_end:
ns.loop_iterations2 += 1
if __name__ == '__main__':
manager = Manager()
ns = manager.Namespace()
ns.loop_iterations1 = 0
ns.loop_iterations2 = 0
p1 = Process(target=loop1, args=(ns,))
p2 = Process(target=loop2, args=(ns,))
p1.start()
p2.start()
p1.join()
p2.join()
print(ns.loop_iterations1)
print(ns.loop_iterations2)
输出(在我的机器上):
5533
5527
我希望在 Raspberry Pi 上使用 Python 多处理来并行读取来自多个 ADC 的值。因此,速度很重要。我运行这两个程序的笔记本电脑有四个内核,所以我无法理解为什么第二个程序中创建的进程只能运行比第一个程序中的单个进程少近 900 倍的迭代。我是否错误地使用了 Python 多处理库?如何使流程更快?
解决方案
我是否错误地使用了 Python 多处理库?
不正确?不,效率低下?是的。
请记住,多处理会创建协作但独立的 Python 实例。把他们想象成工厂的工人,或者做一份大工作的朋友。
如果只有一个人在做一个项目,那么这个人可以在工厂车间自由走动,拿起一个工具,使用它,放下它,移动到其他地方,拿起下一个工具,等等。添加第二个人——或者更糟,更多人,甚至数百人——并且这个人现在必须协调:如果某个区域是共享的,或者某个工具是共享的,Bob 不能随便去拿东西,他必须问 Alice首先,如果她完成了。
对象是 Python 多处理的Manager
通用包装器,用于共享。将变量放入 ManagerNamespace
意味着这些变量是共享的,因此在使用它们之前会自动与其他所有人核对。(更准确地说,它们被保存在一个位置——一个进程——并通过代理从其他位置访问或更改。)
在这里,您已经完成了将“Bob:尽可能快地数数”替换为“Bob:不断打断 Alice 询问她是否在数数,然后数数;Alice:数数,但不断被 Bob 打断”的隐喻等效。到目前为止,鲍勃和爱丽丝大部分时间都花在了彼此交谈上,而不是数数上。
正如文档所说:
...在进行并发编程时,通常最好尽可能避免使用共享状态。在使用多个进程时尤其如此。
(它以“如上所述”开头,但上面没有提到!)。
有许多标准技巧,例如在共享事件之间进行批处理以完成大量工作,或者使用共享内存来加速共享——但是使用共享内存,您需要锁定项目。
推荐阅读
- python - 从 Flask 调用任意 Python 函数的更优雅的方式
- mysql - 围绕经过时间优化 MySQL 查询
- nlp - 尝试训练 spacy ner 管道以添加新命名实体时出现意外类型的 NER 数据
- c# - 与 C# 控制台应用程序中的相同代码相比,Regex.Match 在 Unity 中返回不同/错误的结果
- c++ - 无法解释为什么 c++ 向量分配失败
- android - 如何修复 Android Studio 模拟器总是向上旋转?
- python - 谷歌自己的参考示例甚至不起作用?为 GCS 编写自定义签名 URL
- rabbitmq - 基于 AMQP 的微服务注册和发现
- html - Gsap 滚动触发器混淆
- ios - Swift - 通过 UIRotationGestureRecognizer 旋转多个视图