Python 多处理多线程GIL?
所以,几天以来,我在python上做了很多关于多处理和多线程的研究,我对很多事情感到非常困惑。很多时候,我看到有人在谈论GIL,它不允许Python代码在多个cpu核上执行,但当我编写一个创建多个线程的程序时,我可以看到多个cpu核处于活动状态 第一个问题:吉尔到底是什么?它有用吗?我认为,当一个进程在多个cpu上创建太多线程时,操作系统分布式任务就会发生。我说得对吗Python 多处理多线程GIL?,python,multithreading,multiprocessing,Python,Multithreading,Multiprocessing,所以,几天以来,我在python上做了很多关于多处理和多线程的研究,我对很多事情感到非常困惑。很多时候,我看到有人在谈论GIL,它不允许Python代码在多个cpu核上执行,但当我编写一个创建多个线程的程序时,我可以看到多个cpu核处于活动状态 第一个问题:吉尔到底是什么?它有用吗?我认为,当一个进程在多个cpu上创建太多线程时,操作系统分布式任务就会发生。我说得对吗 另外,我想利用我的CPU。我考虑创建和cpu核心一样多的进程,在这个过程中,每个进程创建和cpu核心一样多的线程。我走对了吗?关
另外,我想利用我的CPU。我考虑创建和cpu核心一样多的进程,在这个过程中,每个进程创建和cpu核心一样多的线程。我走对了吗?关于什么是全局解释器锁(GIL),有很多答案。答案中隐藏着对Python“字节码”的提及,这是问题的核心。编译程序时,输出是字节码,即虚拟“Python”计算机的低级计算机指令,由Python解释器进行解释。当解释器执行字节码时,它通过获取全局解释器锁来序列化执行。这意味着两个线程不能在两个不同的内核上同时执行字节码。但这也是防止这两个线程在更新同一列表时相互干扰的原因。这也意味着没有实现真正的多线程。但这是否意味着没有理由使用线程?不以下是线程仍然有用的几种情况:
numpy
模块就是这样一个高度优化的包因此,当任务不是cpu密集型任务时,最好使用线程,即它们需要大量等待i/O完成,或者需要大量睡眠等。关于全局解释器锁(GIL)是什么,有一些答案。答案中隐藏着对Python“字节码”的提及,这是问题的核心。编译程序时,输出是字节码,即虚拟“Python”计算机的低级计算机指令,由Python解释器进行解释。当解释器执行字节码时,它通过获取全局解释器锁来序列化执行。这意味着两个线程不能在两个不同的内核上同时执行字节码。但这也是防止这两个线程在更新同一列表时相互干扰的原因。这也意味着没有实现真正的多线程。但这是否意味着没有理由使用线程?不以下是线程仍然有用的几种情况:
numpy
模块就是这样一个高度优化的包因此,当任务不是cpu密集型任务时,最好使用线程,即任务需要大量等待i/O完成,或者需要大量睡眠等。首先,GIL只能确保在任何给定时间只运行一条cpython字节码指令。它不关心哪个CPU内核运行指令。这就是操作系统内核的工作 因此,回顾一下你的问题:
def do_nothing(i):
time.sleep(0.0001)
return i*2
ThreadPool(20).map(do_nothing, range(10000))
第一个是多线程的,第二个不是。当您比较这两个程序的CPU使用率时,您会发现在这两种情况下都会触发多个CPU核。所以你所注意到的,虽然是正确的,但与GIL或线程无关。CPU在多个内核中的高使用率只是因为OS内核将根据可用性将代码的执行分配给不同的内核
最后一个问题更像是一个实验性的问题,因为不同的程序有不同的CPU/io使用率。您只需了解创建线程和进程的成本以及GIL&PVM的工作,并优化线程和进程的数量,以获得最大的性能
您可以阅读David Beazley的文章,了解多线程如何使代码性能更差(或更好)。首先,GIL只确保在任何给定的t上只运行一条cpython字节码指令
def do_nothing(i):
time.sleep(0.0001)
return i*2
[do_nothing(i) for i in range(10000)]