简体   繁体   English

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

[英]Setting a Variable inside a Running Thread to Stop the Thread

I have an object cooker whose run() method starts a new thread cookingThread . 我有一个对象cookerrun()方法启动一个新的线程cookingThread After 5 seconds, how can I stop cookingThread by setting its variable stopThread ? 5秒钟后,我怎么能阻止cookingThread通过设置变量stopThread

Tried using cooker.toggle() to first start the thread, but the next cooker.toggle() was not able to stop the thread. 尝试使用cooker.toggle()首先启动线程,但是下一个cooker.toggle()无法停止线程。

The following code gives me the error NameError: global name 'cookingThread' is not defined 下面的代码给我错误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 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. 问题是cookingThread是仅在Cooker.run()方法内部作用域的方法。 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. 并如下更改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

As a rule of thumb when developing Object Oriented Programming never access a field directly like in the case of cookingThread.stopThread . 根据经验,开发面向对象程序设计时切勿直接访问字段(例如cookingThread.stopThread Try to use a method like stop actually to modify. 尝试使用诸如stop的方法进行实际修改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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