以下代码:
import threading
import time
from functools import partial
from itertools import count
def daemon_loop(sleep_interval, stop_event):
for j in count():
print(j)
if stop_event.is_set():
break
time.sleep(sleep_interval)
print('Slept %s' % sleep_interval)
print('Prod terminating')
if __name__ == '__main__':
stop_event = threading.Event() #https://stackoverflow.com/a/41139707/281545
target = partial(daemon_loop, sleep_interval=2, stop_event=stop_event)
prod_thread = threading.Thread(target=target,
# daemon=True
)
try:
prod_thread.start()
while True:
time.sleep(10)
except KeyboardInterrupt:
print('Terminating...')
stop_event.set()
在键盘中断上打印:
C:\Users\MrD\.PyCharm2018.2\config\scratches>c:\_\Python363-64\python.exe thread_daemon.py
0
Slept 2
1
Terminating...
Slept 2
2
Prod terminating
取消对# daemon=True
行的注释会导致prod_thread立即终止:
C:\Users\MrD\.PyCharm2018.2\config\scratches>c:\_\Python363-64\python.exe thread_daemon.py
0
Slept 2
1
Terminating...
我的问题是处理线程终止的首选/更多pythonic方法是什么?我应该放弃事件机制,仅将线程标记为守护程序,还是错过一些边缘情况?
请参阅:
答案 0 :(得分:3)
我做的Python还不够,无法给您“ Pythonic”的答案,但是我可以用更通用的编程术语来回答。
首先,我不喜欢终止线程。在某些情况下,它是安全无事的,例如您在这里的示例,但是在java.io.IOException: com.sun.enterprise.admin.remote.RemoteFailureException: Error occurred during deployment: Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.lang.ClassNotFoundException: devicemanager.models.Action
的中间终止写其输出会感到有点脏。
第二,如果您想继续使用print
(我也不喜欢),可以在之后重复sleep
和if stop_event.is_set():
睡觉。 (不要移动代码,将其复制。)在这种情况下,break
的主要问题在于,即使在该时间段内设置了事件,它也会等待完整的sleep
。
第三次,也是我的喜好,而不是使用sleep_interval
,而是在事件超时的情况下执行sleep
。如果在等待期间未设置事件,则wait
在等待超时时间后返回false。如果事件是在等待之前或等待期间设置的,则wait
立即
因此您的代码应如下所示:
wait