【问题标题】:Is it safe to add a new method to Python Thread class?向 Python Thread 类添加新方法是否安全?
【发布时间】:2013-11-07 02:48:05
【问题描述】:

我想向 Thread 子类添加一个新方法,这样我就可以告诉我的工作线程优雅地退出。像这样:

class MyThread(threading.Thread):
    def __init__(self):
        ...
        self.__stop_signal = False
        self.__signal_lock = threading.Lock()
        ...

    def run(self):
        ...
        self.__signal_lock.acquire(True)
        stop_signal = self.__stop_signal
        self.__signal_lock.release()
        if stop_signal:
            return
        ...

    def stop_elegantly(self):
        self.__signal_lock.acquire(True)
        self.__stop_signal = True
        self.__signal_lock.release()

那么这样做安全吗?:

thread = MyThread()
thread.start()
...
thread.stop_elegantly()

谢谢。

【问题讨论】:

    标签: python multithreading


    【解决方案1】:

    是的,看起来不错。事实上,您可以通过以下方式更“优雅”地做到这一点:

    def stop_elegantly(self):
        with self.__signal_lock:
            self.__stop_signal = True
    

    实际上,我认为您甚至不需要锁来访问成员变量,因为将为您的子类的每个实例分配一个单独的锁。例如,参见这个answer,它将stop() 方法添加到threading.Thread 子类。

    【讨论】:

    • 谢谢。关于锁,我认为在某些极端情况下锁是必要的(比如当内存中的值与缓存中的值不同时)。当然在这里使用 lock 有点过头了。
    • @kkpattern:在我看来,cpu 硬件会在单个线程中处理任何内存与缓存内存的差异。无论如何,感谢您选择我的答案。顺便说一句,如果您认为值得,这里也习惯性地对您接受的答案进行投票。
    【解决方案2】:
        self.__signal_lock.acquire(True)
        stop_signal = self.__stop_signal
        self.__signal_lock.release()
    

    上面的代码在循环中?如果是,我认为效果很好。

    【讨论】:

    • 对不起,我的意思是从另一个线程调用方法stop_elegantly() 是否安全。 Python 文档说不要覆盖除run()__init__() 以外的方法,但没有说明添加新方法并调用它。
    • 嗯。 stop_elegantly() 由您的代码中的主线程调用,不是吗?我认为主线程是您上面评论中的另一个线程。
    • 是的,你是对的。在主线程中调用 Thread 类的方法是安全的,例如 join()。我想知道在 Thread 子类中调用自己添加的方法是否也安全。
    猜你喜欢
    • 1970-01-01
    • 2021-02-11
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多