2017-01-06 44 views
1

我創建了一個async python協同程序async def,我想在列表中的每個元素上運行它。如何同時運行`n` python協同程序?

但是,協程啓動了一個單獨的進程,並且我的計算機資源有限,所以我只想同時運行這些協同程序的n。當一個人結束時,我想另一個人開始。

我還在學習asyncio,我迷失在這個框架內如何做到這一點。

我知道我可以同時使用這樣的運行n作業:

commands = asyncio.gather(*[run_command(f) for f in islice(my_large_list,n)]) 
# Run the commands 
results = loop.run_until_complete(commands) 

不過,我不知道如何爲它更換完成每個作業。

+0

你想'asyncio'使用'multiporcessing'?如果是這樣的話:我試着用踏板;不完全相同,但可能會讓你知道如何到達那裏, –

+0

我不想用asyncio進行多處理。我試圖調用一個外部進程...另一種方式來說明:我想要併發性,而不是並行性。 –

+0

對不起,我很困惑... asyncio會在單個線程上運行;無需擔心有限的資源。 otoh:啓動進程*將*導致並行性(不是併發性)。那是哪個呢?你可以發佈你的協同程序的玩具例子嗎? (我會對你如何「等待」你開始的一個過程感興趣)。 –

回答

3

一種選擇是使用asyncio.Semaphore

import asyncio 

import random 

s = asyncio.Semaphore(5) 


async def my_coroutine(i): 
    async with s: 
     print("start", i) 
     await asyncio.sleep(random.uniform(1, 3)) 
     print("end", i) 


loop = asyncio.get_event_loop() 
tasks = [my_coroutine(i + 1) for i in range(50)] 
loop.run_until_complete(asyncio.gather(*tasks)) 
loop.close() 

更新concurrent.futures可能會解決你的問題比asycnio一個更簡單的方法,因爲執行者有一個非常簡單max_workers說法:

import concurrent.futures 
import time 

import random 


def my_routine(i): 
    print("start", i) 
    # Here you can use subprocess.* for anything, instead we will sleep: 
    time.sleep(random.uniform(1, 3)) 
    print("end", i) 
    return "i={}".format(i) 


with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor: 
    jobs = {executor.submit(my_routine, i + 1) for i in range(50)} 
    for fut in concurrent.futures.as_completed(jobs): 
     print(fut.result()) 

print('done') 
+1

我認爲對於IO任務來說,ThreadPoolExecutor比ProcessPoolExecutor更受歡迎 – Neil