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()
furas.pl