https://code.tutsplus.com/articles/introduction-to-parallel-and-concurrent-programming-in-python--cms-28612 从我研究的这个链接,我几乎没有问题 Q1:线程池(并发)和线程在这里有何不同?为什么我们看到性能提升。使用Que的线程有4个线程,每个线程在空闲时间内协同运行,并在获得网站响应后从Que中选择项目。正如我所见,线程池也在做同样的事情。完成工作并等待经理分配任务;这与从Que中选择一个新项目非常相似。我不确定这有什么不同,为什么我看到了perfroamcne改进。在这里解释极化似乎我错了。你可以expalin
Q2:问题2:使用多处理所花费的时间更多。如果我有多处理器可以一次处理多个进程,那么我的所有4个进程应该一次处理它。这就是真正的并行化正在发生。此外,我在这里有一个问题 - 在这种情况下,由于4个进程正在运行相同的功能,因此GIL不会尝试阻止它们执行同一段代码。让我们假设它们共享一个更新的公共变量 - 就像检查的网站数量一样。那么GIL如何在这些多处理的情况下工作呢? 此外,这里是一次又一次使用相同的过程,或者他们在工作后每次都被杀死和创建 - 我认为使用相同的过程。此外,我认为性能问题是由于在并发线程阶段与轻量级线程相比创建了流程 - 这是昂贵的。那么你能详细解释一下GIL如何在这里工作并且进程正在运行,它们是否正在协同运行(就像每个进程等待它一样 - 就像进程中的线程一样)。或者这些使用多处理器的进程是否真正并行运行。另外,我的另一个问题是如果我有一台8核机器,我想我可以同时或并行地运行同一进程的8个线程。如果我有8核机器,我可以运行2个进程,每个进程有4个线程吗?我可以在8个核心上运行8个进程吗?我认为核心只适用于进程的线程,这意味着我无法在8个核心上运行8个进程,但我可以运行尽可能多的进程数量的CPU或多处理器系统,我是对的吗?那我可以运行2个进程,每个进程有4个线程吗?在我的8核机器上有2个多处理器,每个处理器有4个核心?
答案 0 :(得分:2)
Python有一组丰富的库,用于使用进程和线程进行多任务处理。但是,库之间存在重叠,选择取决于您查看计算任务的抽象程度。例如,concurrent.futures
库将线程视为异步任务,而Threading
库将它们作为高级线程处理。此外,_thread
实现了一个低级接口,用于线程化暴露所有同步机制。
GIL (全局解释器锁)只是一个同步原语,特别是mutex
,它可以阻止同一进程的多个线程执行Python字节码片段(对于某些需要与并发操作保持一致的对象)。与计算密集型任务相比,这正是Python线程在速度方面优于I / O操作的原因。(由于GIL是在某些阻塞调用/计算密集型库(例如numpy
)的情况下发布的。 )。请注意,只有 CPython 和 Pypy 版本的Python受GIL机制约束。
现在,让我们看看这些问题......
- 线程池(并发)和线程如何在这里不同?为什么我们看到性能提升?
醇>
在线程和 concurrent.futures.ThreadPoolExecutor (又名threading_squirrel vs future_squirrel)之间进行比较时,我已经使用相同的测试用例执行了这两个程序。有两个因素促成了这一点"性能改进":
网络HEAD请求:请记住,每次执行网络操作时都不需要在同一时间段内完成...由于数据包传输延迟的本质......
线程执行顺序:在您链接的网站中,作者最初创建所有线程,设置充满网站链接的队列,然后在列表推导循环中启动所有线程。在ThreadPoolExecutor
的{{1}}中,每次提交任务时,如果尚未达到预定义的最大线程数/工作数,则会为其分配一个线程。我已经改变了代码以反映这种技术。 似乎提高了速度,因为第一个线程很早就开始工作,并且不需要等待队列被填满...
- GIL如何在这些多处理的情况下工作?
醇>
请记住,GIL仅对进程的线程生效,而不对进程生效。 GIL在执行线程期间锁定整个解释器字节码,因此其他线程必须等待轮到他们。这就是concurrent.futures
使用流程而不是线程的原因,因为每个流程都拥有它自己的解释器,因此,它是自己的GIL。
- 是否一次又一次地使用相同的流程,或者每次工作后都会被杀死并创建?
醇>
池的概念是减少在计算过程中创建和销毁工作者(无论是线程还是进程)的开销。然而,这些过程是一种全新的"从某种意义上说,库有效地要求操作系统在基于UNIX的操作系统中执行multiprocessing
或在基于NT的操作系统中执行fork
...
- 此外,这些流程是否合作运行?
醇>
也许。如果他们使用共享内存,他们有在合作中运行......(不需要一起运行)。如果有多个进程而不是操作系统可以分配给它的处理器,那么肯定会有一个上下文切换。核心。如果没有共享内存更新,它们可以并行运行。
- 如果我有8核心机器,我可以运行2个进程,每个进程有4个线程吗?我可以在8个核心上运行8个进程吗?
醇>
当然(以GIL为准,在Python中)。可以将每个进程分配给每个处理单元以供执行。处理单元可以是CPU的物理或虚拟核心。只要OS调度程序支持它,它就是可能的。任何合理的都可以分离进程和线程。如果所有都是可分配的,那就是最好的情况,否则你会遇到上下文切换......(当涉及到流程时会更贵)
希望我已经回答了所有这些问题!
以下是一些资源:
MultiCore CPUs, Multithreading and context switching?
Why does multiprocessing use only a single core after I import numpy?