Home > database >  Killing a python thread
Killing a python thread

Time:11-30

I would like to kill somehow a running thread from my GUI application via setting an event, but I can't use a for loop in my thread so I need some other solution to check the event

I have the following situation. In a tkinter gui when I click a button I start a thread and set a global variable.

self.thread = StoppableThread(caller=self)
self.thread.start()
is_running = 1

When I next click the button I check the global variable state and if it is already set I send a stop request:

if is_running:
    is_running = 0
    self.thread.stop()

This is my thread class:

import threading
from time import sleep


class StoppableThread(threading.Thread):
    def __init__(self, caller=None):
        super(StoppableThread, self).__init__()
        self._stop_event = threading.Event()
        self.caller = caller

    def stop(self):
        self._stop_event.set()

    def stopped(self):
        return self._stop_event.is_set()

    def run(self) -> None:
        while True:
            # check for stop
            if self.stopped():
                break

            for i in range(10):
                sleep(1)
                print('Test')

            print('Worker done')
            break

Everything works if I change the while to a for loop, but because in this point in my business logic I doesn't have anything to loop for I need to check somehow different the state of the self.stopped(). Is there any way to check it in the while loop?

Or how can I achive this? I tried to use process instead of thread but it wasnt worked because of an error 'process can't pickle tkinter'.

Thank you for any help

CodePudding user response:

This loop will run forever until you set the flag:

    def run(self):
        while not self.stopped():
            sleep(1)
            print('Test')

You don't actually need an event. A simple Boolean will do.

FOLLOWUP

Here's an example based on your code that shows how this works:

import threading
from time import sleep

class StoppableThread(threading.Thread):
    def __init__(self, caller=None):
        super(StoppableThread, self).__init__()
        self._stop_event = False
        self.caller = caller

    def stop(self):
        self._stop_event = True

    def stopped(self):
        return self._stop_event

    def run(self) -> None:
        while not self.stopped():
            sleep(1)
            print('Test')
        print("exited")

thread = StoppableThread(caller=None)
thread.start()
sleep(5)
thread.stop()
sleep(1)
print("program ending")
  • Related