首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Python 3.2开始,GIL有改进吗?

从Python 3.2开始,GIL有改进吗?
EN

Stack Overflow用户
提问于 2019-11-09 15:54:55
回答 2查看 91关注 0票数 4

我正在研究Python的GIL是如何工作的。我正在从下面的幻灯片中学习,但我有一个问题。

http://www.dabeaz.com/python/UnderstandingGIL.pdf

这张幻灯片描述了Python 3.2中的新GIL,并提供了概述。其中,作为新的GIL的一个缺点,引入了不能有效处理I/O绑定线程的护航效应。

而且,作为一个潜在的改进,有一种可能性可以通过根据线程是受I/O限制还是受CPU限制来赋予优先级来解决这一问题。

这样的改进实际上是从Python 3.2开始实现的吗?如果已经实现,请介绍相关内容。

EN

回答 2

Stack Overflow用户

发布于 2021-12-01 22:28:15

从Python 3.10开始,Dave建议的修复或其他修复还没有在Python中实现。这是relevant issue,目前关闭为wontfix,所以可以放心地说,这个护航效应问题也不会在不久的将来得到解决,至少。

我的理解是,目前还不清楚这是否真的是一个影响生产中代码的问题,而且修复会触及Python的一个危险部分。这就是不情愿的原因。如果它被证明是生产系统中遇到的实际问题,而不仅仅是一个理论问题,我认为讨论将会转移。

票数 2
EN

Stack Overflow用户

发布于 2021-12-02 02:25:35

确实比GIL有所改进,但基线并没有改变。然而,它与许多python用例完全无关。

因为:

  • 许多应用程序将时间花在IO等待上,也就是网络、存储等--基本上就是在等待,什么也不做。这意味着同时没有其他python代码在运行,然后它可以释放GIL并允许其他代码使用run.
  • Asynchronous编程。

来自Fluent python:

这就是为什么David Beazley说:“

线程擅长什么都不做。”

Python标准库中的每个阻塞I/O函数都会释放GIL,允许其他线程运行。time.sleep()函数还释放GIL。因此,Python线程在受I/O限制的应用程序中完全可用,尽管GIL.

我认为这就是为什么pypy3 -使用python实现python的项目-是世界上使用GIL的最快的python解释器。因为当实现并行是绝对必要的时候,你有其他选择。

演示GIL并不重要

使用异步编程的IO密集型工作演示:

Asyncio:

代码语言:javascript
复制
import asyncio
import httpx

test_url = "https://speed.hetzner.de/100MB.bin"


async def download_task(url: str):
    async with httpx.AsyncClient() as client:
        print("Start downloading!")
        data = await client.get(url)
        print(f"Data received! Resp: {data.status_code} / Received: {len(data.content)}")


async def beeper(sec: int):
    while True:
        await asyncio.sleep(sec)
        print(f"Beep! {sec}")


async def main():
    dl_task = asyncio.create_task(download_task(test_url))
    asyncio.create_task(beeper(1))

    await dl_task

asyncio.run(main())

三人组:

代码语言:javascript
复制
import trio
import httpx

test_url = "https://speed.hetzner.de/100MB.bin"


class DownloadComplete(Exception):
    pass


async def download_task(url: str):
    async with httpx.AsyncClient() as client:
        print("Start downloading!")
        data = await client.get(url)
        print(f"Data received! Resp: {data.status_code} / Received: {len(data.content)}")

        raise DownloadComplete


async def beeper(sec: int):
    while True:
        await trio.sleep(sec)
        print(f"Beep! {sec}")


async def main():
    try:
        async with trio.open_nursery() as nursery:
            nursery.start_soon(download_task, test_url)
            nursery.start_soon(beeper, 1)
    except DownloadComplete:
        pass

trio.run(main)
代码语言:javascript
复制
Start downloading!
Beep! 1
...
Beep! 1
Beep! 1
Data received! Resp: 200 / Received: 104857600

CPU密集型工作演示:

代码语言:javascript
复制
from multiprocessing import pool


def work(val):
    return hash(val ** 10000000)


if __name__ == '__main__':
    p = pool.Pool(8)

    with p:
        output = p.map(work, [i for i in range(1, 31)])

    print(output)

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

https://stackoverflow.com/questions/58777429

复制
相关文章

相似问题

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