2016-11-12 44 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')