创建“单例”线程 - 如何在任何时候最多拥有一个线程实例

时间:2012-02-15 23:35:24

标签: python multithreading singleton

我希望有一个类(从threading.Thread继承),它是从程序中的多个位置初始化和启动的。我想要避免的是如果线程已经从其他地方运行,如果程序中的另一个地方试图启动它

t= somemodule.TheThread(some,args)
t.start()

程序可以继续执行(但是只有在相同的线程尚未在此处或其他地方运行时,线程才会启动。)

我可以想到一些不太优雅的方法来设置标志,但必须有一个很好的方法来解决这个问题。我用装饰器查看单例类型模式或覆盖 new ,但主要问题是如果我保持相同的实例是你不能(我知道)调用启动不止一次,甚至如果线程已经完成。

我考虑过在anther对象中创建线程对象,可以检查当前线程是否仍在运行,但是我无法确定如何保持这个线程安全。

有人有任何想法吗?

3 个答案:

答案 0 :(得分:6)

您应该使用函数来创建和启动线程,并且该函数可以使用自己的簿记来了解线程是否已经启动。不要忘记让簿记线程安全!

试图让调用者相信他正在创建和创建一个线程,当他可能不是时,就会比它的价值更麻烦。在任何情况下,将此常见操作封装在函数中都是一个好主意,并为您提供所需的控件。

答案 1 :(得分:0)

检查somemodule.TheThread线程是否存活的一种简单方法如下:

any(isinstance(thread, somemodule.TheThread)
    for thread in threading.enumerate())

答案 2 :(得分:0)

在应用启动时启动线程并让它等待事件。如果事件被设置,则线程完成其工作,重置事件并再次等待它。一旦其他线程通过设置事件'启动'循环线程,任何数量的其他线程都可以调用'set'无效,直到循环线程完成其工作,清除事件并再次等待。

没有线程微管理,没有可能存在多个线程实例,没有线程 - 不安全,没有标志,没有可疑的线程状态检查。

在循环线程完成其工作和清除事件之间有一个小窗口,其中将忽略来自另一个线程的集合。使用您选择的设计很难消除这种不确定性。您可以使用信号量而不是事件,并在顶部使用获取(假)循环来检查信号量是否已发出信号,并确保其计数再次为零。如果已发信号通知信号量,则线程可以再次运行其工作。如果信号量尚未发出信号,则可以等待它直到信号量为止。