我发现在Python 3.4中,有几个不同的多处理/线程库:multiprocessing vs threading vs asyncio。
但我不知道该用哪一个,或者是“推荐的”。它们做的事情是一样的,还是不同的?如果是的话,哪个是用来干什么的?我想在我的计算机上写一个使用多核的程序。但我不知道该学哪个图书馆。
我发现在Python 3.4中,有几个不同的多处理/线程库:multiprocessing vs threading vs asyncio。
但我不知道该用哪一个,或者是“推荐的”。它们做的事情是一样的,还是不同的?如果是的话,哪个是用来干什么的?我想在我的计算机上写一个使用多核的程序。但我不知道该学哪个图书馆。
当前回答
这是基本思想:
是IO-BOUND吗?----------->使用asyncio 它的cpu量大吗?--------->使用多处理 其他的吗?---------------------->使用线程
所以基本上坚持线程,除非你有IO/CPU问题。
其他回答
多处理 每个进程都有自己的Python解释器,并且可以在处理器的独立内核上运行。Python multiprocessing是一个包,它支持使用类似于threading模块的API生成进程。多处理包提供了真正的并行性,通过使用子进程而不是线程,有效地避开了全局解释器锁。
当你有CPU密集型任务时,使用多处理。
多线程 Python多线程允许在进程中生成多个线程。这些线程可以共享进程的相同内存和资源。在CPython中,由于全局解释器锁,在任何给定的时间都只能运行一个线程,因此你不能利用多个内核。由于GIL的限制,Python中的多线程并不能提供真正的并行性。
Asyncio Asyncio致力于协作多任务概念。Asyncio任务运行在同一个线程上,因此没有并行性,但它为开发人员提供了更好的控制,而不是操作系统,这是多线程的情况。
关于asyncio相对于线程的优点,在这个链接上有一个很好的讨论。
Python摘要中的多处理VS线程VS AsyncIO
They are intended for (slightly) different purposes and/or requirements. CPython (a typical, mainline Python implementation) still has the global interpreter lock so a multi-threaded application (a standard way to implement parallel processing nowadays) is suboptimal. That's why multiprocessing may be preferred over threading. But not every problem may be effectively split into [almost independent] pieces, so there may be a need in heavy interprocess communications. That's why multiprocessing may not be preferred over threading in general.
asyncio(该技术不仅在Python中可用,其他语言和/或框架也有它,例如Boost.ASIO)是一种有效处理来自多个同步源的大量I/O操作的方法,而不需要并行代码执行。因此,它只是针对特定任务的解决方案(确实是一个不错的解决方案!),而不是用于一般的并行处理。
博士TL;
做出正确的选择:
我们已经介绍了最流行的并发形式。但问题依然存在——什么时候应该选择哪一个?这实际上取决于用例。根据我的经验(和阅读),我倾向于遵循以下伪代码:
if io_bound:
if io_very_slow:
print("Use Asyncio")
else:
print("Use Threads")
else:
print("Multi Processing")
CPU绑定=>多处理 I/O绑定,快速I/O,有限数量的连接=>多线程 I/O受限,慢I/O,多连接=> Asyncio
参考
【注意】:
如果你有一个很长的调用方法(例如,一个包含睡眠时间或惰性I/O的方法),最好的选择是asyncio, Twisted或Tornado方法(协程方法),它与单个线程一起工作作为并发。 asyncio适用于Python3.4及更高版本。 Tornado和Twisted从Python2.7开始就准备好了 Uvloop是超快的asyncio事件循环(Uvloop使asyncio快2-4倍)。
(更新(2019)):
Japranto (GitHub)是一个非常快速的基于uvloop的流水线HTTP服务器。
这是基本思想:
是IO-BOUND吗?----------->使用asyncio 它的cpu量大吗?--------->使用多处理 其他的吗?---------------------->使用线程
所以基本上坚持线程,除非你有IO/CPU问题。
In multiprocessing you leverage multiple CPUs to distribute your calculations. Since each of the CPUs runs in parallel, you're effectively able to run multiple tasks simultaneously. You would want to use multiprocessing for CPU-bound tasks. An example would be trying to calculate a sum of all elements of a huge list. If your machine has 8 cores, you can "cut" the list into 8 smaller lists and calculate the sum of each of those lists separately on separate core and then just add up those numbers. You'll get a ~8x speedup by doing that.
In (multi)threading you don't need multiple CPUs. Imagine a program that sends lots of HTTP requests to the web. If you used a single-threaded program, it would stop the execution (block) at each request, wait for a response, and then continue once received a response. The problem here is that your CPU isn't really doing work while waiting for some external server to do the job; it could have actually done some useful work in the meantime! The fix is to use threads - you can create many of them, each responsible for requesting some content from the web. The nice thing about threads is that, even if they run on one CPU, the CPU from time to time "freezes" the execution of one thread and jumps to executing the other one (it's called context switching and it happens constantly at non-deterministic intervals). So if your task is I/O bound - use threading.
asyncio本质上是线程,而不是CPU,而是你,作为一个程序员(或者实际上是你的应用程序),决定何时何地发生上下文切换。在Python中,您使用await关键字来暂停协程的执行(使用async关键字定义)。