0

I'm doing a telemetry application using Azure IoT Hub, Azure IoT SDK in Python and a raspberry pi with temperature and humidity sensors.

Humidity + Temperature sensors => Rasperry Pi => Azure IoT Hub

For my application, I send the data with different frequencies using 2 looping threads: - One loop collect the data of the temperature sensor and send it to Azure IoT Hub every 60 seconds -One loop collect the data of the humidity sensor and send it to Azure IoT Hub every 600 seconds.

I want to close properly the 2 looping threads. They currently run with no way to break them.

I'm using Python 2.7. I heard about Event from of the library "threading, Thread", but I can't find some good example of program structure to apply.

How can I use Event to close properly thread? How to end those loops with another method?

Here is the structure of my code using the 2 threads including loop.

from threading import Thread

def send_to_azure_temperature_thread_func:
    client = iothub_client_init()
    while True:
        collect_temperature_data()
        send_temperature_data(client)
        time.sleep(60)

def send_to_humidity_thread_func():
    client = iothub_client_init()
    while True:
        collect_humidity_data()
        send_humidity_data(client)
        time.sleep(600)

if __name__ == '__main__':
    print("Threads...")
    temperature_thread = Thread(target=send_to_azure_temperature_thread_func)
    temperature_thread.daemon = True
    print("Thread1 init")

    humidity_thread = Thread(target=send_to_azure_humidity_thread_func)
    humidity_thread.daemon = True
    print("Thread2 init")

    temperature_thread.start()
    humidity_thread.start()
    print("Threads start")

    temperature_thread.join()
    humidity_thread.join()
    print("Threads wait")
trotta
  • 1,232
  • 1
  • 16
  • 23
Anthony
  • 71
  • 1
  • 10

1 Answers1

0

Event seems like a good approach. Create one and pass it to all threads and replace the sleep() by Event.wait() and check if the loop needs to be left.

In the main thread the event can be set to signal to the threads that they should leave the loop and thus end themselves.

from threading import Event, Thread


def temperature_loop(stop_requested):
    client = iothub_client_init()
    while True:
        collect_temperature_data()
        send_temperature_data(client)
        if stop_requested.wait(60):
            break


def humidity_loop(stop_requested):
    client = iothub_client_init()
    while True:
        collect_humidity_data()
        send_humidity_data(client)
        if stop_requested.wait(600):
            break


def main():
    stop_requested = Event()

    print('Threads...')
    temperature_thread = Thread(target=temperature_loop, args=[stop_requested])
    temperature_thread.daemon = True
    print('Thread1 init')

    humidity_thread = Thread(target=humidity_loop, args=[stop_requested])
    humidity_thread.daemon = True
    print('Thread2 init')

    temperature_thread.start()
    humidity_thread.start()
    print('Threads start')

    time.sleep(2000)
    stop_requested.set()

    temperature_thread.join()
    humidity_thread.join()
    print('Threads wait')


if __name__ == '__main__':
    main()
BlackJack
  • 4,476
  • 1
  • 20
  • 25
  • Why using event.wait(60) instead of time.sleep(60)? I have got the feeling that the event will be trigger after 60 second, so it's no more a loop, right? I want to send messages every 60 seconds and later, to trig the event when I want (for closing the program for example). Thks for answering! – Anthony Jun 27 '19 at 12:52
  • Because `event.wait(60)` will stop as soon the event is set while `time.sleep(60)` still waits the 60 seconds. This is even more relevant for the 600 second wait in the humidity function. `wait()` doesn't trigger the event it waits for the event to be triggered. – BlackJack Jun 27 '19 at 12:58
  • Great! How should I define Event()? Will Event() handle any input? like mouse clik, enter, A, B, ...? – Anthony Jun 28 '19 at 08:24
  • `Event` is defined in `threading` and an instance is created in the first line of the `main()` function. And _you_ have to call `set()` on it to trigger it whenever you think you want to stop the threads. In the example I simply wait 2000 seconds before doing so. Of course you can do something different to determine when to trigger the `Event`. – BlackJack Jun 28 '19 at 14:23