coroutines가 미래에 선점 될 수 있기 때문입니까? 아니면 사람들이 중요한 섹션에서 수익을 사용할 수 있습니다 (IMO는 권장하지 말아야 함)?파이썬 asyncio.Lock()은 무엇입니까?
답변
임계 값 섹션을 보호하기 위해 스레드 코드에서 잠금을 사용하는 것과 같은 이유로 이것을 사용합니다. asyncio
은 기본적으로 단일 스레드 코드에서 사용하기위한 것이지만 동시 실행이 발생하기 때문에 때때로 동기화가 필요합니다.
@asyncio.coroutine
def get_stuff(url):
if url in cache:
return cache[url]
stuff = yield from aiohttp.request('GET', url)
cache[url] = stuff
return stuff
지금 당신은 동시에 그 잠재적해야 할 수도 있습니다 실행하는 여러 공동 루틴을 가지고 있다고 가정 :
예를 들어, 다음 웹 서버에서 일부 데이터를 가져 오는 및 기능을 고려하여 결과를 캐시합니다
def parse_stuff():
stuff = yield from get_stuff()
# do some parsing
def use_stuff():
stuff = yield from get_stuff()
# use stuff to do something interesting
def do_work():
out = yield from aiohttp.request("www.awebsite.com")
# do some work with out
tasks = [
asyncio.async(parse_stuff()),
asyncio.async(use_stuff()),
asyncio.async(do_work()),
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
지금, url
에서 데이터를 가져 오는 것은 느린 인 척 : get_stuff
의 반환 값을 사용합니다. parse_stuff
과 use_stuff
이 동시에 실행되는 경우 각각은 stuff
을 가져 오기 위해 네트워크를 통해 이동하는 데 드는 모든 비용이 부과됩니다. 당신이 잠금 방법을 보호하는 경우에는이를 방지 :
stuff_lock = asyncio.Lock()
def get_stuff(url):
with (yield from stuff_lock):
if url in cache:
return cache[url]
stuff = yield from aiohttp.request('GET', url)
cache[url] = stuff
return stuff
주목해야 할 또 다른 일이 하나 코 루틴 내부 get_stuff
의 aiohttp
통화를하고, stuff_lock
다른 대기, 아무튼 제 코 루틴 동안 Lock
에있는 코 루틴 차단에 영향을받지 않고 get_stuff
에 전화 할 필요가 전혀 없습니다.
분명히이 예제는 조금 고안된 것이지만, 잘하면 그것은 asyncio.Lock
이 유용한 이유에 대한 아이디어를 제공합니다. 이 실행되지 않도록 다른 coroutine을 차단하지 않고도 중요한 섹션을 보호 할 수 있습니다.은 해당 중요 섹션에 액세스해야합니다.
자세한 설명을 주셔서 감사합니다. 질문을 이해하지 못하는 사람들을 위해 요약 해 보겠습니다. 1) coroutine을 선점 할 수 없습니다. "yield from"이 컨트롤을 루프로 되돌릴 때까지 실행됩니다. 2) asyncio.Lock()은 "yield from"을 호출하는 중요 섹션을 보호하는 데 사용됩니다. 그렇지 않으면 잠금을 사용할 필요가 없습니다. 토론은 단일 스레드 asyncio 사용 모드를 가정합니다. – user3761759
dano가주는 좋은 예로서 나는 질문에서 말한 것을 반복해야합니다. 저는 개인적으로 중요한 섹션에서 "yield from"을 사용하는 아이디어를 좋아하지 않습니다. 그것은 부적절한 것 같지만 나는 그것을 말해야 만합니다. – user3761759
dano -이 특정 예제 (실제로 고안되었음을 명심하십시오)에서 'yield from'을 제거하고 차단 HTTP 요청을 만든 경우 동일한 성능을 얻지 못합니까? 그대로 잠그기 때문에,'get_stuff()'의 인스턴스가 단 한 번만 진행됩니다. (인스턴스 B는 인스턴스 A가 완전히 완료되었을 때만 인스턴스 B가 시작될 수있다.) –
잠금 장치, 선점과 관련이 있는지 확실하지 않은 잠금 장치를 얻으려고하면 잠금 장치를 들고있는 상태에서 다시 제어 장치가 제공되기를 기대합니다. 하나의 코 루틴이 한 번에 입력 할 수있는 중요한 섹션을 가지기 위해서입니다. 그것은 문서에 모두 있습니다. –
공식적인 문서를주의 깊게 읽거나 질문을 이해할 것이라고 생각하지 않습니다. – user3761759