在正在运行的线程内设置变量以停止线程

时间:2014-03-13 08:33:31

标签: python multithreading python-2.7

我有一个对象cooker,其run()方法启动一个新线程cookingThread。 5秒后,如何通过设置变量cookingThread停止stopThread

尝试使用cooker.toggle()首先启动线程,但下一个cooker.toggle()无法停止该线程。

以下代码给出了错误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)

主要

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

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

1 个答案:

答案 0 :(得分:1)

问题是cookingThread仅在Cooker.run()方法中的方法作用域。错误在于您需要将其声明为全局,以便能够从所有方法进行访问。但这不是一个好习惯。

您可以做的是以下

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()

按照以下方式更改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)

    def stop(self):
        self.stopThread = True

根据经验,开发面向对象编程时,永远不会像cookingThread.stopThread那样直接访问字段。尝试使用stop之类的方法实际修改。