当前位置: 首页 > 面试题库 >

为什么Python I / O绑定任务没有被GIL阻止?

索锐藻
2023-03-14
问题内容

该蟒蛇线程
文档指出“......线程仍然是一个合适的模型,如果你想同时运行多个I / O密集型任务”,这显然是因为I /
O密集型进程能够避免GIL是在并行执行的线程阻止受CPU限制的任务。

但是我不明白的是,一个I / O任务仍然使用CPU。那么它怎么可能不会遇到相同的问题呢?是否因为I / O绑定任务不需要内存管理?


问题答案:

将在CPython的GIL 1中
涉及执行Python代码。使用大量CPU的线程安全C扩展可能会释放GIL,只要它不需要与Python运行时进行交互即可。

一旦C代码需要与Python“对话”(请参阅​​:回调到Python运行时),则它需要再次获取GIL-
也就是说,GIL将为“解释器”建立保护/原子行为(并且我使用的术语是宽松的), 并不是 要防止本机/非Python代码同时运行。

释放GIL周围的I / O(阻塞或不使用CPU与否)是同样的事情-直到数据被移动 的Python没有理由获取GIL。

1 GIL之所以引起争议,是因为它在某些情况下阻止多线程CPython程序充分利用多处理器系统。请注意,潜在的阻塞或长时间运行的操作(例如I /
O,图像处理和NumPy数字运算)发生在GIL之外。因此 ,只有在GIL内部花费大量时间解释CPython字节码的多线程程序中, GIL才成为瓶颈。



 类似资料:
  • GIL(global interpreter lock),全局解释器锁,是很多编程语言实现中都具有的特性,由于它的存在,解释器无法实现真正的并发。它也是 Python 中经常讨论的话题之一。 Python 作为编程语言存在多个具体实现,包括最常用的 CPython、超集 Cython、.NET 平台的 IronPython、JVM 上的 Jython,R 语言实现的 RPython、JIT 版本的

  • 问题内容: 来自python线程文档 在CPython中,由于使用了全局解释器锁,因此只有一个线程可以一次执行Python代码(即使某些面向性能的库可以克服此限制)。如果希望您的应用程序更好地利用多核计算机的计算资源,建议您使用多处理。但是,如果您要同时运行多个I / O绑定任务,则线程化仍然是合适的模型。 现在我有一个这样的线程工作者 这里做两件事 使用库抓取网址 使用JavaScript库分析

  • 我对ArrayBlockingQueue进行了一个简单的测试,如下所示: 结果是: 我的问题是,我已经将ArrayBlockingQueue的大小定义为3,而制作人将2、0和1放入队列,总共3个项目,现在队列已满,然后消费者消费了0,队列大小现在应为2,然后制作人将4放入队列,现在队列应已满,为什么制作人仍可以将6放入队列,应该被阻止

  • 问题内容: 我希望有人能够提供一些有关Java虚拟机的根本差异的见解,从而使Java虚拟机可以很好地实现线程而无需使用全局解释器锁(GIL),而Python则需要这样做。 问题答案: Python(该语言)不需要GIL(这就是为什么它可以在JVM [Jython]和.NET [IronPython]上完美实现的原因,并且这些实现可以自由地使用多线程)。CPython(流行的实现)一直使用GIL来简

  • 问题内容: 我已经看到了有关根据索引值从中获取对象的其他问题,并且我理解为什么这是不可能的。但是我无法找到一个很好的解释,说明为什么不允许按对象获取,所以我想问一下。 有a作为后盾,因此从中获取对象应该非常简单。现在看来,我将不得不遍历中的每个项目并测试是否相等,这似乎是不必要的。 我可以只使用a,但不需要key:value对,我只需要一个。 例如说我有: 和: 是否因为equals方法用于测试“

  • 问题内容: 我编写了以下程序: 由于通道事件列表是一个缓冲通道,我想我应该获得100倍的输出“嘿!”,但是它只显示一次。我的错误在哪里? 问题答案: 更新(Go 1.2版或更高版本) 从Go 1.2开始,调度程序基于 抢先式多任务处理 原则。这意味着原始问题(以及下面提供的解决方案)中的问题不再相关。 从Go 1.2发行说明中 调度程序中的抢占 在以前的版本中,永远循环的goroutine可能会使