首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多线程GIL?

多线程GIL?
EN

Stack Overflow用户
提问于 2020-08-17 15:36:52
回答 2查看 7.6K关注 0票数 8

所以,自从几天以来,我在python上做了很多关于多线程和多线程的研究,我对很多事情都很困惑。很多时候,我看到有人在谈论GIL --一些不允许Python代码在几个cpu核心上执行的东西--但是当我编写一个创建多个线程的程序时,我可以看到几个cpu内核是活动的。

第一个问题:什么是真正的吉尔?起作用了吗?我想到的是,当一个进程创建了太多线程时,操作系统就会在多cpu上分配任务。我说的对吗?

另外,我想利用我的cpus。我想到了一些东西,比如创建和cpu内核一样多的进程,在这个基础上,每个进程创建的线程和cpu内核一样多。我在右车道上吗?

EN

回答 2

Stack Overflow用户

发布于 2020-08-21 05:04:04

首先,GIL只确保在任何给定时间只运行一个cpython字节码指令。它不关心哪个CPU核心运行指令。这是操作系统内核的工作。

所以仔细考虑一下你们的问题:

  1. 吉尔只是一段代码。CPython虚拟机是首先将代码编译成Cpython的过程,但它的正常工作是解释CPython字节码。GIL是一段确保一次运行一行字节码的代码,不管有多少线程正在运行。构成虚拟机堆栈的是Cpython字节码指令。因此,在某种程度上,GIL将确保在任何给定的时间点上只有一个线程持有GIL。(同时,它不断地为其他线程释放GIL,而不是让它们挨饿。)

现在进入你真正的困惑。您提到,当您使用多个线程运行一个程序时,您可以看到多个(可能是全部) CPU核心启动。所以我做了一些实验,发现你的发现是正确的(这是显而易见的),但是在一个非线程版本中,这种行为也是相似的。

代码语言:javascript
复制
def do_nothing(i):
    time.sleep(0.0001)
    return i*2

ThreadPool(20).map(do_nothing, range(10000))
代码语言:javascript
复制
def do_nothing(i):
    time.sleep(0.0001)
    return i*2

[do_nothing(i) for i in  range(10000)]

第一个是多线程的,第二个不是。当您通过两个程序比较CPU使用情况时,您会发现在这两种情况下,多个CPU核心都会触发。所以,你注意到的,虽然是正确的,但与吉尔或线程无关。CPU在多核中的使用率很高,原因很简单,因为OS内核将根据可用性将代码的执行分发给不同的内核。

你的最后一个问题是一个实验性的问题,因为不同的程序有不同的CPU/io使用。您只需了解创建线程和进程的成本,以及GIL & PVM的工作情况,并优化线程和进程的数量,以获得最大的优先级。

您可以通过David的这次谈话来了解多线程如何使您的代码执行得更糟(或者更好)。

票数 12
EN

Stack Overflow用户

发布于 2020-08-17 16:04:46

有关于什么是全球解释器锁(GIL)是这里的答案。答案之一是提到Python“字节码”,这是这个问题的核心。在编译程序时,输出是字节码,即由Python解释器解释的虚构的"Python“计算机的低级计算机指令。当解释器执行字节码时,它通过获取全局解释器锁来序列化执行。这意味着两个线程不能在两个不同的核心上并发执行字节码。这也意味着没有实现真正的多线程。但这是否意味着没有理由使用线程呢?不是的!以下是线程仍然有用的几种情况:

  1. 对于某些操作,解释器将释放GIL,例如,在执行I/O时,您需要从不同的网站获取大量的URL。大多数时间用于等待请求发出后返回的响应,即使必须连续地完成请求的制定,此等待也可能重叠。
  2. 许多Python函数和模块都是用C语言实现的,不受任何GIL限制。numpy模块就是这样一个高度优化的包。

因此,当任务不是cpu密集型时,最好使用线程,例如,它们会做大量等待I/O完成的工作,或者做大量的睡眠等等。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63454072

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档