我可以想到两种方法来打破Python线程中的循环,下面是最简单的例子:
1 - 使用哨兵值
from threading import Thread, Event
from time import sleep
class SimpleClass():
def do_something(self):
while self.sentinel:
sleep(1)
print('loop completed')
def start_thread(self):
self.sentinel = True
self.th = Thread(target=self.do_something)
self.th.start()
def stop_thread(self):
self.sentinel = False
self.th.join()
simpleinstance = SimpleClass()
simpleinstance.start_thread()
sleep(5)
simpleinstance.stop_thread()
2 - 使用活动
from threading import Thread, Event
from time import sleep
class SimpleThread(Thread):
def __init__(self):
super(SimpleThread, self).__init__()
self.stoprequest = Event()
def run(self):
while not self.stoprequest.isSet():
sleep(1)
print('loop completed')
def join(self, timeout=None):
self.stoprequest.set()
super(SimpleThread, self).join(timeout)
simpleinstance = SimpleThread()
simpleinstance.start()
sleep(5)
simpleinstance.join()
在Python文档中,它讨论了事件,但没有讨论更简单的“哨兵”值。方法(我看到在Stack Overflow上的许多线程答案中使用过)。
使用哨兵值有什么不利之处吗?
具体来说,它是否会导致错误(我从来没有过错,但我想如果你试图在为while循环读取的同一时刻改变哨兵的值,那么有些东西可能会破坏(或者可能是CPython)在这种情况下,GIL会救我。)什么是最好的(最安全的)练习?
答案 0 :(得分:1)
如果您查看Event
的来源,您会发现您使用的功能对您没有任何价值:
class Event:
def __init__(self):
self._cond = Condition(Lock())
self._flag = False
def is_set(self):
return self._flag
def set(self):
with self._cond:
self._flag = True
self._cond.notify_all() # No more-value, because you are not using Event.wait
所以在你的情况下Event
只是一个没有实际使用的哨兵值的花哨包装,这也会使你的操作时间减慢真的微小的数量。
事件仅在您使用wait
方法时才有用。