asyncio에는이 작업을 수행하는 기본 방법이 있습니까? 을 (를) 찾을 수 없습니까?
아니요, 아니요, asyncio에는 coroutine-functions를 작업으로 전송할 데코레이터가 없습니다.
제가이 문제로 시작한다면 잘못 했나요?
당신이하고있는 것을 보지 않고 말하기는 어렵지만, 사실일지도 모릅니다. asyncio 프로그램에서 작업을 만드는 것은 일반적인 작업이지만, 나는 당신이이 작업을 항상해야하는 많은 coroutine을 만들지는 모르겠다. "비동기 적으로 어떤 함수를 호출"하는 방법입니다,하지만이 완료 될 때까지 현재의 실행 흐름을 차단 -
코 루틴을 위해 기다리는 :
await some()
# you'll reach this line *only* when some() done
작업을 다른 한편으로는 - 방법을 "실행 기능 in background"입니다 우리가 asyncio
프로그램을 작성할 때 우리는 일반적으로 다음 일을 시작하기 전에 몇 가지 작업의 결과를 필요로하기 때문에
task = asyncio.ensure_future(some())
# you'll reach this line immediately
은 우리가 일반적으로 첫 번째 방법이 필요합니다 :
, 그것은 현재의 실행 흐름을 차단하지 않습니다
text = await request(url)
links = parse_links(text) # we need to reach this line only when we got 'text'
다른 한편으로 작업을 만드는 것은 대개 다음 코드가 작업 결과에 의존하지 않는다는 것을 의미합니다. 그러나 다시는 항상 그런 일은 일어나지 않습니다. asyncio.gather이 사용하는 것입니다 달성하기
# wrong way to run concurrently:
asyncio.ensure_future(request(url1))
asyncio.ensure_future(request(url2))
asyncio.ensure_future(request(url3))
올바른 방법 :
# correct way to run concurrently:
await asyncio.gather(
request(url1),
request(url2),
request(url3),
)
이 될 수
ensure_future
이후 수익률은 즉시 어떤 사람들은 concurently 일부 코 루틴을 실행하는 방법으로 그것을 사용하려고 니가 원하는거야?
UPD :
나는 귀하의 경우 사용하여 작업이 좋은 아이디어라고 생각합니다. 하지만 당신은 데코레이터를 사용해야한다고 생각하지 않습니다. (요청을하기 위해) 코 루틴 (coroutine) 기능은 여전히 구체적인 사용법의 세부 사항 (작업으로 사용됨)과 별개의 부분입니다.요청 동기화 제어가 주요 기능과 다른 경우 동기화를 별도의 기능으로 이동하는 것이 좋습니다. 나는 이런 식으로 뭔가를 할 것이다 :
import asyncio
async def request(i):
print(f'{i} started')
await asyncio.sleep(i)
print(f'{i} finished')
return i
async def when_ready(conditions, coro_to_start):
await asyncio.gather(*conditions, return_exceptions=True)
return await coro_to_start
async def main():
t = asyncio.ensure_future
t1 = t(request(1))
t2 = t(request(2))
t3 = t(request(3))
t4 = t(when_ready([t1, t2], request(4)))
t5 = t(when_ready([t2, t3], request(5)))
await asyncio.gather(t1, t2, t3, t4, t5)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main())
finally:
loop.run_until_complete(loop.shutdown_asyncgens())
loop.close()
감사합니다. 나는 asyncio.gather를 알고 있었지만 coroutine의 가장 큰 문제점 중 하나는 단지 한 번만 기다릴 수 있다는 것입니다. 내가하려는 것은 다음과 같다. 3 개의 요청을 보낸다. 요청 1과 2가 끝나면 요청 4를 전송합니다. 요청 2와 3이 끝나면 요청 5를 보내라. 나는 4 번 작업에 1, 2 번 작업을 보내고 5 번 작업에서 2, 3 번 작업을 모으고있다. 요청 5가 전송되기 전에 요청 1을 완료하거나 요청 4가 전송하기 전에 요청 3을 완료 할 때까지 기다릴 필요가 없습니다. –
@BrettBeatty 나는 대답을 업데이트했다. –
흠 흥미로운 접근 방법입니다. 마지막으로 t4와 t5 만 수집하면됩니다. –