我想知道 python 线程是并发运行还是并行运行?
例如,如果我有两个任务并在两个线程中运行它们,它们是同时运行还是计划同时运行?
我知道GIL并且线程仅使用一个 CPU 核心。
这是一个复杂的问题,需要大量解释。我将坚持使用 CPython,只是因为它是使用最广泛的并且是我有经验的。
Python 线程是一个system需要 Python 解释器在运行时将其内容本地执行为字节码的线程。 GIL 是一个特定于解释器(在本例中为 CPython)的锁,它强制每个线程acquire解释器上的锁,防止两个线程同时运行,无论它们位于哪个核心。
NoCPU 核心一次可以运行多个线程。你need多核甚至可以明智地谈论并行性。并发与并行不同 - 前者意味着两个线程之间的操作可以在任一线程完成之前交错,但两个线程不需要同时启动,而后者意味着可以在两个线程完成之前交错操作。started同时。如果这让您感到困惑,关于差异的更好描述是here https://stackoverflow.com/questions/1050222/concurrency-vs-parallelism-what-is-the-difference.
有多种方法可以在单核 CPU 中引入并发性 - 即让线程挂起(使自己进入睡眠状态)并在需要时恢复 - 但有no引入单核并行性的方法。
由于这些事实,因此,这取决于情况。
系统线程本质上被设计为并发的——否则操作系统就没有意义了。它们是否实际上以这种方式执行取决于任务:某处是否存在原子锁? (正如我们将看到的,确实存在!)
-
执行受 CPU 限制的计算的线程(其中正在执行大量代码,并且同时为每行动态调用解释器)获得 GIL 上的锁,以防止其他线程执行相同的操作。所以,在that在这种情况下,所有核心一次只有一个线程工作,因为没有其他线程可以获取解释器。
话虽这么说,线程don't需要保留 GIL 直到它们完成,而不是根据需要获取和释放锁。两个线程可以交错操作,因为 GIL 可以在代码块末尾释放,被另一个线程抓住,在代码块末尾释放。that代码块等等。他们不会跑进来parallel- 但它们当然可以同时运行。
另一方面,I/O 绑定线程花费大量时间只是等待请求完成。这些线程不会获取 GIL - 当没有什么可以解释时,为什么它们会获取 GIL? - 所以当然可以让多个 I/O 等待线程并行运行,每个线程一个核心。然而,分钟代码需要编译为字节码(也许您需要处理您的请求?)GIL 再次上升。
Python 中的进程在 GIL 中幸存下来,因为它们是与线程捆绑在一起的资源集合。每个过程都有其own解释器,因此每个thread一个进程只需与它自己的直接兄弟进程竞争 GIL。这就是为什么基于进程的并行性是 Python 中推荐的方法,尽管它总体上消耗更多的资源。
结果
所以两个线程中有两个任务could run in parallel前提是他们不需要访问 CPython 解释器。如果它们正在等待 I/O 请求或正在使用不需要 Python 解释器的合适的其他语言(例如 C)扩展,使用外部函数接口,则可能会发生这种情况。
所有线程都可以运行同时在交错原子操作的意义上。究竟如何atomic这些交错可以是 - GIL 是否在代码块之后被释放?每行之后? - 取决于任务和线程。 Python 线程不必串行执行——一个线程完成,然后另一个线程开始——因此从这个意义上讲,存在并发。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)