2016-11-12 1 views
1

asyncio를 사용하여 nodeJS와 비슷한 작업을 처리하는 방법을 궁금합니다. 스레드를 열지 않고 동시에 작업을 실행하고 싶습니다. 예 :병렬 작업에 asyncio 사용

import asyncio 

@asyncio.coroutine 
def my_coroutine(task_name, seconds_to_sleep=3): 
    print('{0} sleeping for: {1} seconds'.format(task_name, seconds_to_sleep)) 
    yield from asyncio.sleep(seconds_to_sleep) 
    print('{0} is finished'.format(task_name)) 


loop = asyncio.get_event_loop() 
tasks = [ 
    my_coroutine('task1', 4), 
    my_coroutine('task2', 3), 
    my_coroutine('task3', 2)] 
loop.run_until_complete(asyncio.wait(tasks)) 
loop.close() 

출력됩니다 :

task1 sleeping for: 4 seconds 
task2 sleeping for: 3 seconds 
task3 sleeping for: 2 seconds 
task3 is finished 
task2 is finished 
task1 is finished 

하지만 다른 작업과 그것을 수행하려고 할 때 그런 식으로 작동하지 않습니다.

import asyncio 
import timeit 

@asyncio.coroutine 
def my_coroutine(task_name): 
    print('order placed for ' + task_name) 
    print(timeit.timeit('1 + 3 ', number=50000000)) 
    print(task_name + ' done') 


loop = asyncio.get_event_loop() 
tasks = [ 
    my_coroutine('task1'), 
    my_coroutine('task2'), 
    my_coroutine('task3')] 
loop.run_until_complete(asyncio.wait(tasks)) 
loop.close() 

출력

order placed for task2 
0.6677237730912453 
task2 done 
order placed for task1 
0.6627442526498016 
task1 done 
order placed for task3 
0.665618849882418 
task3 done 
+0

asyncio는 병렬로 실행하지 않습니다. 기다릴 때까지 하나의 작업을 실행 한 후 다음 작업으로 이동합니다. 당신의 첫 번째 예제에서 잠은 작업이 서로에게 통제력을 갖도록 만드는 것입니다. 두 번째 예제는 아무 것도 기다리지 않으므로 각 태스크는 완료 될 때까지 실행되어 이벤트 루프가 다른 태스크를 제어 할 수 있습니다. – dirn

+0

나는 본다. 그렇다면 두 번째 코드를 비동기식 작업으로 만드는 방법은 무엇입니까? 나는 수익률을 추가하려고했지만 첫 번째 예제처럼 여전히 효과가 없습니다. – Zepol

+0

어떻게 'yield from'을 추가 했습니까? asyncio.sleep (n)에서 yield를 추가 했습니까? 아니면 다른 작업을 수행 했습니까? – dirn

답변

3

asyncio 병렬로 일을 실행하지 않습니다. 기다릴 때까지 하나의 작업을 실행 한 후 다음 작업으로 이동합니다. 첫 번째 예제의 sleep은 작업이 서로 제어하도록 만드는 것입니다. 두 번째 예제는 아무 것도 기다리지 않으므로 각 태스크는 완료 될 때까지 실행되어 이벤트 루프가 다른 태스크를 제어 할 수 있습니다.

진행중인 항목 (예 : asyncio.sleep)을 코 루틴에 추가하면 각각이 제어권을 부여하고 다른 사용자에게 실행할 기회를줍니다.

@asyncio.coroutine 
def my_coroutine(task_name): 
    print('order placed for ' + task_name) 
    yield from asyncio.sleep(0) # Another coroutine will resume here. 
    print(timeit.timeit('1 + 3 ', number=50000000)) 
    yield from asyncio.sleep(0) # Another coroutine will resume here. 
    print(task_name + ' done')