[英]Python asyncio wait for threads
我有一種情況,我有一個“服務器”線程,它應該偵聽來自其他服務器線程的調用/事件,同時執行其他一些代碼。 最近我在 Node.js 上做了很多工作,所以我認為使用 async/await 創建一個事件循環會很好,我可以在其中等待其他線程加入事件循環並在它們最終加入時處理它們的響應。
為了測試這個想法,我在 Python 3.5 中編寫了以下測試腳本:
# http://stackabuse.com/python-async-await-tutorial/
# Testing out Python's asynchronous features
import asyncio
from time import sleep
import threading
from threading import Thread
import random
class MyThread(Thread):
def __init__(self, message):
Thread.__init__(self)
self._message = message
def run(self):
self._return = self._message + " oli viesti"
a = random.randint(1, 5)
print("Sleep for ", a)
sleep(a)
print("Thread exiting...")
def join(self):
Thread.join(self)
return self._return
async def send(message):
t = MyThread(message) # daemon = True
t.start()
print("asd")
return t.join()
async def sendmsg(msg):
response = await send(msg)
print("response is ", response)
if __name__ == "__main__":
# Initiate a new thread and pass in keyword argument dictionary as parameters
loop = asyncio.get_event_loop()
tasks = [
asyncio.ensure_future(sendmsg("hippa1"), loop=loop),
asyncio.ensure_future(sendmsg("hippa2"), loop=loop),
asyncio.ensure_future(sendmsg("hippa3"), loop=loop)
]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
在這個例子中,我想用不同的字符串啟動三個工作線程並等待它們完成。 工人的睡眠時間是隨機的,所以我希望他們在多次運行腳本時以隨機順序完成。 事實證明,它們似乎是按順序執行的,第二個線程在第一個線程之后開始。
我的錯誤是什么? sleep 不應該只阻塞它所在的線程嗎? 我的事件循環設置正確嗎? 我可以異步/等待加入嗎?
最終我想向其他線程發送消息並等待他們的響應然后運行帶有返回值的回調函數。
編輯:為了澄清,最終我想在我的主線程中等待帶有 async/await 的條件變量並運行其他代碼,直到某些條件變量讓執行通過。 在這個示例代碼中,我試圖對工作線程的連接做同樣的事情。
最終,由於以下代碼,它按順序運行:
async def send(message):
t = MyThread(message) # daemon = True
t.start()
print("asd")
return t.join()
您啟動一個線程,然后立即等待該線程完成,然后再繼續。 這就是它們順序執行的原因。
Node.js 和 asyncio 不一定會創建新線程來執行它們的操作。 例如,Node.js 只使用單個線程,但它使用內核級函數(例如 'epoll' )來調用您指示何時發生某些新網絡活動的回調。 這允許單個線程管理數百個網絡連接。
這就是為什么當您在沒有 Thread 實例的情況下執行此操作時,您可能會在當前運行的線程上調用 sleep,這與主線程相同。 當您將 asyncio 與網絡功能一起使用時,您可以使用“yield from”結構,它允許其他代碼塊在其他任務與其他遠程服務一起執行時執行。
主要結構是正確的。 你想要這個代碼塊:
loop.run_until_complete(asyncio.wait(tasks))
但是不要依賴'sleep'來測試功能,需要進行網絡調用,或者使用:
yield from asyncio.sleep(1)
在這種情況下不需要啟動單獨的線程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.