'Sending data with sampling rate to different channels using Asyncio
I am trying to simulate a program that sends signals from a sensor using Python and Asyncio. The sensor has multiple addresses. Each signal will be sent to a specific address with a sampling rate periodically. My idea is to write a multitasking program to solve the problem. I find Asyncio helpful to write concurrent programs. Basically, my program looks like that:
import asyncio
from datetime import datetime
async send_data(publisher, data, address, samplingRate):
print(f"{publisher.name} will sleep for {samplingRate} seconds")
await asycio.sleep(samplingRate);
publisher.send(data, address);
print(f"Sending {data} at {address}")
async dispatch():
pub1 = Publisher("Pub1")
pub2 = Publisher("Pub2")
point1 = 5
point2 = 10
tasks = [
send_data(pub1, point1, "30001", 2),
send_data(pub2, point2, "30002", 6)
]
await asyncio.gather(*tasks)
print("------------------------------")
if __name__ == '__main__':
while True:
asyncio.run(dispatch())
The output of this program looks like that:
1. Pub1 will sleep for 2 seconds
2. Pub2 will sleep for 6 seconds
3. Sending 5 at address 3001 #this will be displayed after 2 seconds from the first line.
4. Sending 10 at address 3002 #this will be displayed after 6 seconds from the second line.
------------------------------
#Then the output runs periodically.
The output shows the program works well with the concurrent criteria. However, it fails with sampling criteria. With publisher "pub1", pub1 should send the data twice with its samplingRate insteading doing nothing while waiting for the pub2 sending action completes. In other words, the output should display:
1. Pub1 will sleep for 2 seconds
2. Pub2 will sleep for 6 seconds
3. Sending 5 at address 3001 #this will be displayed after 2 seconds from the first line.
4. Sending 5 at address 3001 #this will be displayed after 4 seconds from the first line.
5. Sending 10 at address 3002 #this will be displayed after 6 seconds from the second line.
------------------------------
#Then the output runs periodically.
As my understanding from this article, there is a event loop which is responsible for controlling two send_data() tasks for "pub1" and "pub2". The event loop will pick the task from the queue to run. When "await asycio.sleep(samplingRate)" is called, context switch occurs. The event loop will pause the current task, save its state and pick another task in queue to execute. Then the event loop goes back to task1 for pub1 from where it left. Because two tasks do the same action, when the task1 finishes sending data or finishes its job. It can only wait for the second task completes instead of doing send_data() task for the second time.
My question is how to apply Asyncio to create a program which can run concurrent tasks. Each task can run with it sampling rate exactly instead of doing nothing while waiting other to finish.
Thank you so much for your time!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
