Python Jak uruchomić dwa procesy w tym samym czasie w asyncio
Problem jest jak uruchomić send_data()
i read_data()
w tym samym czasie w asyncio
.
Nie można użyć run()
do wystartowaniw dwóch procesów w tym samym czasie w asyncio.
run()
startuje jeden proces i czeka na jego zakończenie - tak więc run(send_data())
startuje funkcję send_data
i czeka na jej zakończenie - i dlatego nie może uruchomić read_data
.
Jeśli zmienić kolejność to run(read_data())
będzie czekać na zakończenie read_data
i nie uruchomi send_data
run()
można użyc to uruchomienia funkcji, która użyje create_task()
dla send_data()
i read_data()
.
Należy najpierw stworzyć zadania a potem użyć ich z await
ponieważ w przeciwnym przypadku nie wystartuje druga funkcjation
W przykładdzie w obu funkcjach jest użyte asyncio.sleep()
aby w obu mieć jakąś funkcję z await
.
import queue
import asyncio
import datetime
data_queue = queue.Queue()
async def send_data():
print("send data")
while True:
data = str(datetime.datetime.now())
print('put:', data)
# add data to queue
data_queue.put(data)
await asyncio.sleep(2)
async def main():
print("read data")
while True:
# read queued data from serial port
if not data_queue.empty():
data = data_queue.get()
print('get:', data)
await asyncio.sleep(1)
async def start():
print("start")
#await send_data() # doesn't work
#await read_data() # doesn't work
# I had to create all tasks before running
task1 = asyncio.create_task(send_data())
task2 = asyncio.create_task(read_data())
# running task
await task1
await task2
asyncio.run(start())
Ale prostrzą metodą jest użycie asyncio.gather()
async def start():
print("start")
await asyncio.gather(
send_data(),
read_data(),
)
Reszta jest taka sama w poprzedniej wersji
import queue
import asyncio
import datetime
data_queue = queue.Queue()
async def send_data():
print("send data")
while True:
data = str(datetime.datetime.now())
print('put:', data)
# add data to queue
data_queue.put(data)
await asyncio.sleep(2)
async def main():
print("read data")
while True:
# read queued data from serial port
if not data_queue.empty():
data = data_queue.get()
print('get:', data)
await asyncio.sleep(1)
async def start():
print("start")
await asyncio.gather(
send_data(),
read_data(),
)
asyncio.run(start())
Notes:
Stackoverflow serial_asyncio: read serial port into a queue and read that queue from main() not working
BTW: Problem z queue
:kiedy nie ma danych w kolejce queue
wtedy get()
może zablokować kod i lepiej jest sprawdzać czy kolejka nie jest pusta empty()
Buy a Coffee