【Python开发】Python中的多处理
Chinese, Simplified
- Why Python Multiprocessing
- 在 Python 中,单 CPU 使用是由全局解释器锁 (GIL) 引起的,它在任何给定时间只允许一个线程携带 Python 解释器。实现 GIL 是为了处理内存管理问题,但因此,Python 仅限于使用单个处理器。
- 模块的多处理允许程序员充分利用给定机器上的多个处理器。使用的 API 类似于经典的线程模块。它提供本地和远程并发。
- 多处理模块通过使用子进程而不是线程来避免全局解释器锁 (GIL) 的限制。多处理代码的执行顺序与串行代码不同。不能保证第一个创建的进程将是第一个完成的。
为什么多处理有用?
计算从 1 到 1000 的所有数字的最快方法是什么?
- Python 一次只使用一个内核来工作。想想在解决一个简单的数学问题时做什么更快。
- 通过将结果一一相加,并以递增方式将总和相加(1+2=3、3+3=6,6+4=1000,依此类推)。一个核心正在处理这项任务。
- 预先将值拆分为单独的块,然后先将那里的值相加(1 到 300、301 到 600 和 601 到 1000)。三个核心将同时工作(最后一步是将收到的三个值相加)。
一个好的起点是了解 Python 中的多处理库是如何工作的。
你应该使用什么?
- 如果你的代码有很多 I/O 或网络使用:多线程是你最好的选择,因为它的开销很低
- 如果你有一个 GUI:多线程,这样你的 UI 线程就不会被锁定
- 如果您的代码受 CPU 限制:您应该使用多处理(如果您的机器有多个内核)
多处理示例
- Multiprocessing 是一个使用类似于 threading 模块的 API 支持生成进程的包。
- multiprocessing 包提供本地和远程并发,通过使用子进程而不是线程来有效地避开全局解释器锁。
- 因此,模块的多处理允许程序员充分利用给定机器上的多个处理器。 它可以在 Unix 和 Windows 上运行。
- 这个使用 Pool 的数据并行的基本示例,
from multiprocessing import Pool def f(x): return x*x if __name__ == '__main__': with Pool(5) as p: print(p.map(f, [1, 2, 3]))
将打印到标准输出:
[1, 4, 9]
进程类
在多处理中,进程是通过创建一个 Process 对象然后调用它的 start() 方法来产生的。 进程遵循threading.Thread的API。 多进程程序的一个简单示例是
from multiprocessing import Process def f(name): print('hello', name) if __name__ == '__main__': p = Process(target=f, args=('bob',)) p.start() p.join()
为了显示所涉及的各个进程 ID,这是一个扩展示例:
from multiprocessing import Process import os def info(title): print(title) print('module name:', __name__) print('parent process:', os.getppid()) print('process id:', os.getpid()) def f(name): info('function f') print('hello', name) if __name__ == '__main__': info('main line') p = Process(target=f, args=('bob',)) p.start() p.join()
过程和例外:
- run():方法代表进程的活动。
- start():启动进程的活动。
- join([timeout]):如果可选参数 timeout 为 None(默认值),则该方法将阻塞,直到调用该方法的 join() 的进程终止。
- 名称:进程的名称。该名称是一个仅用于识别目的的字符串。
- is_alive():返回进程是否存活。
- terminate():终止进程
- kill():与 terminate() 相同,但在 Unix 上使用 SIGKILL 信号。
- close():关闭 Process 对象,释放与之相关的所有资源。
- 异常 multiprocessing.ProcessError:所有多处理异常的基类。
- 异常 multiprocessing.BufferTooShort:当提供的缓冲区对象太小而无法读取消息时,Connection.recv_bytes_into() 会引发异常。
- 异常 multiprocessing.AuthenticationError:出现身份验证错误时引发
- 异常 multiprocessing.TimeoutError:超时到期时由具有超时的方法引发
管道和队列
当使用多个进程时,通常使用消息传递来进行进程之间的通信,并避免使用任何同步原语,如锁。
对于传递消息,可以使用 Pipe()(用于两个进程之间的连接)或队列(允许多个生产者和消费者)。
结论
- 如果没有多处理,Python 程序会因为 GIL(全局解释器锁)而无法最大化系统的规格。
- 多处理允许您创建可以同时运行的程序(绕过 GIL)并使用整个 CPU 内核。 虽然它与线程库根本不同,但语法非常相似。 多处理库为每个进程提供了自己的 Python 解释器和自己的 GIL。
- 因此,与线程相关的常见问题(例如数据损坏和死锁)不再是问题。 由于进程不共享内存,因此它们不能同时修改相同的内存。
谢谢阅读。 如果您觉得这篇文章有用,请不要忘记鼓掌并与您的朋友和同事分享。 如果您有任何问题,请随时与我联系。
原文:https://hiteshmishra708.medium.com/multiprocessing-in-python-c6735fa70f…
- 29 次浏览
SEO Title
Multiprocessing in Python