代码之家  ›  专栏  ›  技术社区  ›  Mr_and_Mrs_D

退出python线程的更多pythonic方法-daemon vs stop\u事件

  •  1
  • Mr_and_Mrs_D  · 技术社区  · 6 年前

    以下代码:

    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\u线程立即结束:

    C:\Users\MrD\.PyCharm2018.2\config\scratches>c:\_\Python363-64\python.exe thread_daemon.py
    0
    Slept 2
    1
    Terminating...
    

    我的问题是,处理线程终止的首选/更具python风格的方法是什么-我应该放弃事件机制并将线程标记为守护进程,还是遗漏了一些边缘情况?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Allison Lock    6 年前

    我还没有做足够的Python来给你一个“Pythonic”的答案,但是我可以用更一般的编程术语来回答。

    在安全和正常的情况下,例如您在这里的示例-但在 print 写它的输出会感觉有点脏。

    sleep (我也不喜欢)你可以重复你的话 if stop_event.is_set(): break 之后 睡眠(不要移动代码,复制它。)主要的问题是 睡觉 sleep_interval 即使事件是在这段时间内设置的。

    第三——也是我的偏好——而不是使用 ,做一个 wait 在超时的事件上。如果在等待期间未设置事件, 等待超时时间后返回false。如果事件 等待 返回true (也就是说,它中止超时,使您可以快速、干净地关闭线程。)

    所以你的代码看起来像这样:

    def daemon_loop(sleep_interval, stop_event):
        for j in count():
            print(j)
            if stop_event.wait(sleep_interval):
                break
            print('Slept %s' % sleep_interval)
        print('Prod terminating')