【问题标题】:When the GIL is released?GIL什么时候发布?
【发布时间】:2016-04-29 23:35:52
【问题描述】:

今天,我编写了一个简单的脚本,允许我对 openstack swift 服务器进行基准测试:

import swiftclient
import uuid
from concurrent.futures import ThreadPoolExecutor

def create():
    client = swiftclient.client.Connection(
        user='', key='',
        authurl='https://auth/', auth_version='2.0',
        tenant_name='',
        os_options={'tenant_id': '',
                    'region_name': ''})
    while True:
        uid = str(uuid.uuid4())
        client.put_object(container='', obj=uid, contents=b'\x00')

executor = ThreadPoolExecutor(max_workers=100)
for _ in range(100):
    executor.submit(create)

这很顺利,但我注意到了一件奇怪的事情,该进程的 CPU 使用率达到了 400% 以上。 由于 GIL 不应允许使用超过 100% 的 CPU,这是怎么发生的?

【问题讨论】:

    标签: python python-3.x gil


    【解决方案1】:

    GIL 只防止两个 python 命令同时运行(导致它一次只使用一个 CPU)。但是任何调用 C 的 Python 代码都有可能释放 GIL,直到 C 代码必须再次与 Python SDK 交互,通常是在它返回并将结果编组回 Python 值时。因此,如果 Python 应用程序大量使用 C 库,则它们可能会拥有高度线程化的 Python 应用程序。

    来自GIL上的python wiki

    请注意,可能会阻塞或长时间运行的操作,例如 I/O、图像处理和 NumPy 数字运算,发生在外部 吉尔。因此,只有在多线程程序中才会花费很多 GIL 内部的时间,解释 CPython 字节码,即 GIL 成为瓶颈。

    【讨论】:

    • 在我的代码中,每一个使用的lib都是纯python,你怎么解释?
    • requestsswiftclient 都使用 socket,它有一个 C 组件。在某些时候,所有 CPython 调用到 C 代码中。 I/O 操作(如通过套接字进行的通信)听起来与释放 GIL 的事情完全一样。
    • 这是有道理的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 2011-01-04
    • 2019-05-15
    • 1970-01-01
    • 2010-12-04
    • 2010-11-18
    相关资源
    最近更新 更多