Python 为什么在本例中多个线程的分布效率低下?

Python 为什么在本例中多个线程的分布效率低下?,python,multithreading,Python,Multithreading,我有一个测试,为什么我可以在我的一个内核上运行大约5秒的100%CPU使用时间 这是剧本 from threading import Thread from time import time, sleep def test0(): start = time() a = 0 for _ in range(int(1e8)): a += 1 print(time() - start) def print_after_work(msg): a

我有一个测试,为什么我可以在我的一个内核上运行大约5秒的100%CPU使用时间

这是剧本

from threading import Thread
from time import time, sleep

def test0():
    start = time()
    a = 0
    for _ in range(int(1e8)):
        a += 1
    print(time() - start)
def print_after_work(msg):
    a = 0
    for _ in range(int(1e8)):
        a += 1
    print(msg)
    

def test1():
    threads = []
    for i in range(4):
        threads.append(threading.Thread(target=print_after_work, args=[i+1]))
    start = time()
    for thread in threads:
        thread.start()
        sleep(0.2)
    for thread in threads:
        thread.join()
    print(time() - start)
这是跟踪(Ubuntu 20.04系统监视器,带有1秒时间槽)

酷。这是有道理的。我的一个CPU以100%的速度工作大约5秒钟

现在,如果我尝试运行4个线程,每个线程都做相同的事情,会发生什么?根据我目前的知识,我认为它们应该在一个内核上进行时间分配,整个过程大约需要20秒。这是剧本

from threading import Thread
from time import time, sleep

def test0():
    start = time()
    a = 0
    for _ in range(int(1e8)):
        a += 1
    print(time() - start)
def print_after_work(msg):
    a = 0
    for _ in range(int(1e8)):
        a += 1
    print(msg)
    

def test1():
    threads = []
    for i in range(4):
        threads.append(threading.Thread(target=print_after_work, args=[i+1]))
    start = time()
    for thread in threads:
        thread.start()
        sleep(0.2)
    for thread in threads:
        thread.join()
    print(time() - start)
以下是跟踪:

因此,我们有4个CPU以大约25%的容量工作

问题:

  • 那么Python的
    线程化
    模块可以将线程移动到主进程以外的不同核心
  • 如果是这样的话,那么为什么只使用25%的每个核心,需要4倍的时间来完成呢

  • Python线程不使用多个核心,因为所有线程在内部共享公共数据:


    您在图中看到的是操作系统时间片的聚合效应——几乎可以肯定,Python进程本身在每个时间片上都在核心之间交换。无法保证一个进程将始终固定在同一个核心上。但是,您的图表没有显示O/S时间片的粒度。所以你们看到的是一个4个核的聚合,这意味着您将获得每个CPU的25%或相当于一个CPU的100%——正如您希望在Python多线程上看到的那样,当进程本身被调度时,线程都被绑定到同一个CPU。

    阅读Python GIL摘要-Python线程不使用多个核心,因为所有线程都共享公共数据从内部来看,@AvihayTsayeg有意义,因为所有核心的总和都是100%。但是仍然不确定我的第一个问题的答案。@TonySuffolk66那么为什么在我的示例中有多个核心在工作?@AlexanderSoare O/S Timeslicing-Python进程本身几乎肯定会在每个时间片的核心之间进行交换。无法保证一个进程将始终固定在同一个核心上。您的图表没有显示O/S时间片的粒度。所以你们看到的是一个4核的聚合。