简体   繁体   中英

Setting a Variable inside a Running Thread to Stop the Thread

I have an object cooker whose run() method starts a new thread cookingThread . After 5 seconds, how can I stop cookingThread by setting its variable stopThread ?

Tried using cooker.toggle() to first start the thread, but the next cooker.toggle() was not able to stop the thread.

The following code gives me the error NameError: global name 'cookingThread' is not defined

import threading
import time

class Cooker(object):

    def __init__(self, recipe):
        self.active = False
        self.recipe = recipe

    def toggle(self):
        if not self.active:
            self.active = True
            self.run()

        else:
            self.active = False
            # How can this stop flag be passed into the running thread?
            cookingThread.stopThread = True


    def run(self):
        cookingThread = CookingThread(self.recipe)
        cookingThread.start()

CookingThread

class CookingThread(threading.Thread):

    def __init__(self, recipe):
        super(CookingThread, self).__init__()
        self.recipe = recipe
        self.stopThread = False

    def run(self):
        for i in range(self.recipe):
            # Check if we should stop the thread
            if self.stopThread:
                return
            else:
                print 'Cooking...'
                time.sleep(1)

Main

cooker = Cooker(10)
cooker.toggle()    # Starts the thread

time.sleep(5)
cooker.toggle()    # Stops the thread (does not work)

The issue is cookingThread is method scoped only inside Cooker.run() method. The error is saying that you need to declare it as global to be able to access from all the methods. But that is not a good practice.

What you can do is the following

import threading
import time

class Cooker(object):

    def __init__(self, recipe):
        self.active = False
        self.recipe = recipe

    def toggle(self):
        if not self.active:
            self.active = True
            self.run()

        else:
            self.active = False
            # How can this stop flag be passed into the running thread?
            self.cookingThread.stop()


    def run(self):
        self.cookingThread = CookingThread(self.recipe)
        self.cookingThread.start()

And changing the CookingThread as follow.

class CookingThread(threading.Thread):

    def __init__(self, recipe):
        super(CookingThread, self).__init__()
        self.recipe = recipe
        self.stopThread = False

    def run(self):
        for i in range(self.recipe):
            # Check if we should stop the thread
            if self.stopThread:
                return
            else:
                print 'Cooking...'
                time.sleep(1)

    def stop(self):
        self.stopThread = True

As a rule of thumb when developing Object Oriented Programming never access a field directly like in the case of cookingThread.stopThread . Try to use a method like stop actually to modify.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM