我正在研究Python的GIL是如何工作的。我正在从下面的幻灯片中学习,但我有一个问题。
http://www.dabeaz.com/python/UnderstandingGIL.pdf
这张幻灯片描述了Python 3.2中的新GIL,并提供了概述。其中,作为新的GIL的一个缺点,引入了不能有效处理I/O绑定线程的护航效应。
而且,作为一个潜在的改进,有一种可能性可以通过根据线程是受I/O限制还是受CPU限制来赋予优先级来解决这一问题。
这样的改进实际上是从Python 3.2开始实现的吗?如果已经实现,请介绍相关内容。
发布于 2021-12-01 22:28:15
从Python 3.10开始,Dave建议的修复或其他修复还没有在Python中实现。这是relevant issue,目前关闭为wontfix,所以可以放心地说,这个护航效应问题也不会在不久的将来得到解决,至少。
我的理解是,目前还不清楚这是否真的是一个影响生产中代码的问题,而且修复会触及Python的一个危险部分。这就是不情愿的原因。如果它被证明是生产系统中遇到的实际问题,而不仅仅是一个理论问题,我认为讨论将会转移。
发布于 2021-12-02 02:25:35
确实比GIL有所改进,但基线并没有改变。然而,它与许多python用例完全无关。
因为:
来自Fluent python:
这就是为什么David Beazley说:“
线程擅长什么都不做。”
Python标准库中的每个阻塞I/O函数都会释放GIL,允许其他线程运行。time.sleep()函数还释放GIL。因此,Python线程在受I/O限制的应用程序中完全可用,尽管GIL.
我认为这就是为什么pypy3 -使用python实现python的项目-是世界上使用GIL的最快的python解释器。因为当实现并行是绝对必要的时候,你有其他选择。
演示GIL并不重要
使用异步编程的IO密集型工作演示:
Asyncio:
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())三人组:
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)Start downloading!
Beep! 1
...
Beep! 1
Beep! 1
Data received! Resp: 200 / Received: 104857600CPU密集型工作演示:
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)

https://stackoverflow.com/questions/58777429
复制相似问题