我试图理解多处理相对于线程的优势。我知道多处理绕过了全局解释器锁,但是还有什么其他的优势,线程不能做同样的事情吗?
当前回答
线程模块使用线程,多处理模块使用进程。不同之处在于线程在相同的内存空间中运行,而进程有单独的内存。这使得在多进程之间共享对象变得有点困难。由于线程使用相同的内存,必须采取预防措施,否则两个线程将同时写入同一内存。这就是全局解释器锁的作用。
生成进程比生成线程要慢一些。
其他回答
关键的优势是隔离。进程崩溃不会导致其他进程崩溃,而线程崩溃可能会对其他线程造成严重破坏。
另一件没有提到的事情是,它取决于你使用的是什么操作系统。在Windows中,进程是昂贵的,所以线程在Windows中会更好,但在unix中,进程比它们的Windows变体更快,所以在unix中使用进程要安全得多,而且生成速度快。
正如问题中提到的,Python中的多处理是实现真正并行的唯一方法。多线程无法实现这一点,因为GIL阻止线程并行运行。
As a consequence, threading may not always be useful in Python, and in fact, may even result in worse performance depending on what you are trying to achieve. For example, if you are performing a CPU-bound task such as decompressing gzip files or 3D-rendering (anything CPU intensive) then threading may actually hinder your performance rather than help. In such a case, you would want to use Multiprocessing as only this method actually runs in parallel and will help distribute the weight of the task at hand. There could be some overhead to this since Multiprocessing involves copying the memory of a script into each subprocess which may cause issues for larger-sized applications.
然而,当您的任务是io绑定时,多线程就变得有用了。例如,如果您的大部分任务涉及等待api调用,那么您将使用多线程,因为为什么不在等待时在另一个线程中启动另一个请求,而不是让您的CPU无所事事。
博士TL;
多线程是并发的,用于io绑定的任务 Multiprocessing实现了真正的并行,用于cpu受限的任务
以下是我想到的一些优点和缺点。
多处理
Pros
独立的内存空间 代码通常很简单 利用多个cpu和核 避免了cPython的GIL限制 消除了对同步原语的大部分需求,除非您使用共享内存(相反,它更像是IPC的通信模型) 子进程是可中断/可杀死的 Python多处理模块包含有用的抽象,其接口类似于线程。线程 必须使用cPython进行cpu绑定处理
Cons
IPC有点复杂,开销更大(通信模型vs.共享内存/对象) 更大的内存占用
线程
Pros
轻量级——低内存占用 共享内存-使访问状态从另一个上下文更容易 允许您轻松地创建响应式ui 正确释放GIL的cPython C扩展模块将并行运行 对于I/ o约束应用程序来说是一个很好的选择
Cons
cPython -服从GIL 不是可中断/ killable 如果不遵循命令队列/消息泵模型(使用queue模块),则必须手动使用同步原语(需要对锁定的粒度进行决策) 代码通常更难理解和正确编写——竞争条件的可能性急剧增加
线程模块使用线程,多处理模块使用进程。不同之处在于线程在相同的内存空间中运行,而进程有单独的内存。这使得在多进程之间共享对象变得有点困难。由于线程使用相同的内存,必须采取预防措施,否则两个线程将同时写入同一内存。这就是全局解释器锁的作用。
生成进程比生成线程要慢一些。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 自动化invokerrequired代码模式
- 解析日期字符串并更改格式
- 使用try和。Python中的if