Python支持multithreading吗? 它可以加快执行时间吗?

我对于multithreading是否在Python中工作有些困惑。

我知道有很多这方面的问题,我已经阅读了很多,但我仍然感到困惑。 我从我自己的经验知道,并已经看到其他人发表自己的答案和在Python中的multithreading确实是可能的StackOverflow的例子。 那么为什么每个人都一直说Python被GILlocking,并且一次只能运行一个线程呢? 这显然是工作。 还是有一些区别,我不在这里?

许多海报/受访者也不断提到线程是有限的,因为它不使用多个核心。 但我会说他们仍然是有用的,因为他们同时工作,从而更快地完成组合的工作量。 我的意思是为什么会有一个Python线程模块呢?

更新:

感谢所有迄今为止的答案。 我理解的方式是,multithreading只能针对一些IO任务并行运行,但是一次只能运行一个CPU线程的多核心任务。

我不完全确定这对我来说意味着什么,所以我只是举一个我想要multithreading的任务的例子。 例如,假设我想循环一个非常长的string列表,我想对每个列表项进行一些基本的string操作。 如果我将这个列表分开,发送每个子列表在一个新的线程中由我的循环/string代码处理,并将结果发回队列,这些工作负载是否会同时运行? 最重要的是,这会从理论上加快运行脚本所需的时间?

另一个例子是,如果我可以在四个不同的线程中使用PIL来渲染和保存四张不同的图片,那么这比一个接一个地处理图片要快吗? 我想这个速度组件是我真正想知道的,而不是正确的术语是什么。

我也知道多处理模块,但是我现在的主要兴趣是中小型任务加载(10-30秒),所以我认为multithreading将会更合适,因为subprocess可能启动缓慢。

GIL不妨碍穿线。 GIL所做的是确保一次只有一个线程正在执行Python代码; 控制仍然在线程之间切换。

GIL可以防止的是使用多个CPU内核或单独的CPU来并行运行线程。

这只适用于Python代码。 C扩展可以并释放GIL以允许多个C代码线程和一个Python线程跨多个核心运行。 这延伸到由内核控制的I / O,例如select()调用套接字读写操作,使得Python在multithreading多核设置中合理有效地处理networking事件。

然后执行多个服务器部署,运行多个Python进程,让操作系统处理进程之间的调度,以最大限度地利用您的CPU内核。 如果适合您的用例,您也可以使用multiprocessing库来处理来自一个代码库和父进程的多个进程的并行处理。

请注意,GIL仅适用于CPython实现; Jython和IronPython使用不同的线程实现(分别为本地Java VM和.NET公共运行时线程)。

直接解决你的更新:任何试图通过使用纯Python代码从并行执行中获得速度提升的任务都不会加速,因为线程化的Python代码被locking到一次执行的一个线程。 但是,如果混合使用C扩展和I / O(例如PIL或numpy操作),并且任何C代码都可以与一个活动的Python线程并行运行。

Python线程非常适合创build响应式graphics用户界面,或者用于处理多个短的Web请求,其中I / O比Python代码更为瓶颈。 它不适合并行计算密集型的Python代码,坚持用于这些任务的multiprocessing模块或委托给专用的外部库。

是。 🙂

您有低级别的线程模块和高级线程模块。 但是,您只是想使用多核机器, 多处理模块就是要走的路。

从文档引用:

在CPython中,由于全局解释器锁,只有一个线程可以一次执行Python代码(即使某些面向性能的库可能会克服这个限制)。 如果您希望您的应用程序更好地利用多核计算机的计算资源,build议您使用多处理。 但是,如果要同时运行多个I / O绑定任务,线程仍然是一个合适的模型。