簡體   English   中英

Python asyncio.semaphore in async-await function

[英]Python asyncio.semaphore in async-await function

我正在嘗試自學 Python 的異步功能。 為此,我構建了一個異步 web 刮板。 我想限制我一次打開的連接總數,以便成為服務器上的好公民。 I know that semaphore's are a good solution, and the asyncio library has a semaphore class built in. My issue is that Python complains when using yield from in an async function as you are combining yield and await syntax. 以下是我正在使用的確切語法...

import asyncio
import aiohttp

sema = asyncio.BoundedSemaphore(5)

async def get_page_text(url):
    with (yield from sema):
        try:
            resp = await aiohttp.request('GET', url)
            if resp.status == 200:
                ret_val = await resp.text()
        except:
            raise ValueError
        finally:
            await resp.release()
    return ret_val

引發此異常:

File "<ipython-input-3-9b9bdb963407>", line 14
    with (yield from sema):
         ^
SyntaxError: 'yield from' inside async function

我能想到的一些可能的解決方案......

  1. 只需使用@asyncio.coroutine裝飾器
  2. 使用線程。信號量? 這似乎可能會導致其他問題
  3. 出於這個原因,在 Python 3.6 的 beta 版中試試這個。

我對 Python 的異步功能非常陌生,所以我可能會遺漏一些明顯的東西。

您可以使用async with語句來獲取異步上下文管理器:

#!/usr/local/bin/python3.5
import asyncio
from aiohttp import ClientSession


sema = asyncio.BoundedSemaphore(5)

async def hello(url):
    async with ClientSession() as session:
        async with sema, session.get(url) as response:
            response = await response.read()
            print(response)

loop = asyncio.get_event_loop()
loop.run_until_complete(hello("http://httpbin.org/headers"))

這里取的例子。 該頁面也是asyncioaiohttp一個很好的入門asyncio

OK,所以這是真的很傻,但我只是取代了yield fromawait在信號燈上下文管理器,它是可以正常使用。

sema = asyncio.BoundedSemaphore(5)

async def get_page_text(url):
    with (await sema):
        try:
            resp = await aiohttp.request('GET', url)
            if resp.status == 200:
                ret_val = await resp.text()
        except:
            raise ValueError
        finally:
            await resp.release()
    return ret_val

用於信號量

sem = asyncio.Semaphore(10)

# ... later
async with sem:
    # work with shared resource

相當於

sem = asyncio.Semaphore(10)

# ... later
await sem.acquire()
try:
    # work with shared resource
finally:
    sem.release()

參考: https://docs.python.org/3/library/asyncio-sync.html#asyncio.Semaphore

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM