Skip to content Skip to sidebar Skip to footer

How To Terminate A Thread In Python?

I know the topic has been covered a few times however I have attempted, or at least tried virtually all solutions however being a fairly new python basher I've not been able to get

Solution 1:

Your t1 variable is a local, so it gets lost when you exit the on_message function. Also, you're conflating the class task and the instance t1 (task.stop() won't work).

For a quick fix, declare t1 = None as a global, then add global t1 to your on_message function...

However, I'd consider refactoring things so there's an always-running thread to command the Blinkt!, and the MQTT message handler simply sets its state accordingly – something like this. Dry-coded, obviously, so there may be some silliness.

from sys import exit
import blinkt
import threading
import time

MQTT_SERVER = "192.168.x.x"
MQTT_PORT = 1883
MQTT_TOPIC = "mytopic"

REDS = [0, 0, 0, 0, 0, 16, 64, 255, 64, 16, 0, 0, 0, 0, 0, 0]

start_time = time.time()


classBlinktManager(threading.Thread):
    def__init__(self):
        threading.Thread.__init__(self)
        self.stop_event = threading.Event()
        self.mode = Nonedefrun(self):
        whilenot self.stop_event.isSet():
            self.tick()
            self.stop_event.wait(0.1)  # instead of sleepdeftick(self):
        if self.mode == "reds":
            self._tick_reds()

    def_tick_reds(self):
        delta = (time.time() - start_time) * 16
        offset = int(
            abs((delta % len(REDS)) - blinkt.NUM_PIXELS)
        )

        for i inrange(blinkt.NUM_PIXELS):
            blinkt.set_pixel(i, REDS[offset + i], 0, 0)

        blinkt.show()

    defclear(self):
        self.mode = None
        blinkt.clear()
        blinkt.show()

    defset_all_pixels(self, r, g, b):
        self.mode = Nonefor x inrange(blinkt.NUM_PIXELS):
            blinkt.set_pixel(x, r, g, b)
        blinkt.show()

    defset_pixel(self, x, r, g, b):
        self.mode = None
        blinkt.set_pixel(x, r, g, b)
        blinkt.show()

    defbegin_reds(self):
        self.mode = "reds"defon_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))
    client.subscribe(MQTT_TOPIC)


defon_message(client, userdata, msg):
    data = msg.payload
    iftype(data) isbytes:
        data = data.decode("utf-8")
    data = data.split(",")
    command = data.pop(0)

    if command == "clr"andlen(data) == 0:
        blinkt_manager.clear()

    if command == "rgb"andlen(data) == 4:
        x = data[0]
        r, g, b = [int(x) & 0xFFfor x in data[1:]]
        if x == "*":
            blinkt_manager.set_all_pixels(r, g, b)
        else:
            # TODO: error handling
            blinkt_manager.set_pixel(int(x), r, g, b)

    if command == "mtg"andlen(data) == 0:
        blinkt_manager.begin_reds()


blinkt.set_clear_on_exit()

blinkt_manager = BlinktManager()
blinkt_manager.start()

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_SERVER, MQTT_PORT, 60)
client.loop_forever()

Solution 2:

Python program raising exceptions in a python thread

import threading 
import ctypes 
import time 

classthread_with_exception(threading.Thread):

    def__init__(self, name): 
    threading.Thread.__init__(self) 
    self.name = name 

defrun(self): 

    # target function of the thread class try: 
        whileTrue: 
            print('running ' + self.name) 
    finally: 
        print('ended') 

defget_id(self): 

    # returns id of the respective thread ifhasattr(self, '_thread_id'): 
        return self._thread_id 
    forid, thread in threading._active.items(): 
        if thread is self: 
            returniddefraise_exception(self): 
    thread_id = self.get_id() 
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 
          ctypes.py_object(SystemExit)) 
    if res > 1: 
        ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0) 
        print('Exception raise failure') 

t1 = thread_with_exception('Thread 1') 
t1.start() 
time.sleep(2) 
t1.raise_exception() 
t1.join() 

Post a Comment for "How To Terminate A Thread In Python?"