python - 线程 - 标记值或事件来打破循环
问题描述
我可以想到两种方法来打破 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 可能会保存我在这种情况下)。什么被认为是最好的(最安全的)做法?
解决方案
如果您查看 的来源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
。
推荐阅读
- go - GORM 'NOT IN' subquery
- reactjs - 什么是 redux 中的展示组件或容器组件
- c# - 使用 DataSource 移动 ListBox 中的所有选定项
- sql-server - SQL Server 表分区中列的显式转换
- php - TWIG/Timber dump 功能导致“致命错误”
- python - Putting items into array
- azure-storage - How to Zip files on Storage with ADF
- java - RxJava Networking cannot be instantiated
- java - Spring: Adding one record to a List suddenly creates a duplicate
- java - 更新输入后不存储来自 JTextArea 的预期字符串