优雅地停止线程

时间:2019-06-28 17:45:17

标签: python multithreading

我即将完成程序,我想在发布第一个版本之前解决此错误。

这是我正在谈论的错误:

Exception ignored in: <module 'threading' from '/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py'>
Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 1281, in _shutdown
    t.join()
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 1032, in join
    self._wait_for_tstate_lock()
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 1048, in _wait_for_tstate_lock
    elif lock.acquire(block, timeout):
KeyboardInterrupt

我这样启动线程:

def init(self):

    new_post_stream_thread = threading.Thread(target=self.new_post_stream)
    process_posts = threading.Thread(target=self.process_posts)
    print('\nStarting threads...')
    print('- - - - - - - - - -\n')
    new_post_stream_thread.start()
    process_posts.start()

基本上就是这样。我将如何捕获此异常?除了已经尝试过,我尝试了一下,但它什么也没抓住。

这是MCVE:

import threading
import time

class MCVE:

    def __init__(self):

        self.list_1 = []

        self.init()

    def thread_1(self):

        while True:
            self.list_1.append('whatever')
            time.sleep(5)

    def thread_2(self):

        while True:
            for id, entry in enumerate(self.list_1):
                print('ID {} | entry: {}'.format(id, entry))
            time.sleep(10)

    def init(self):
        thread_1 = threading.Thread(target=self.thread_1)
        thread_2 = threading.Thread(target=self.thread_2)
        print('\nStarting threads...')
        print('- - - - - - - - - -\n')
        thread_1.start()
        thread_2.start()


def main():

    example = MCVE()

if __name__ == "__main__":
    main()

2 个答案:

答案 0 :(得分:1)

您没有提供可复制的示例,但这成功地停止了程序而未引发未捕获的异常:

def foo(n):
    import time
    try:
        for i in range(n):
            time.sleep(i)
    except KeyboardInterrupt:
        print("Clean exit....")
        return

答案 1 :(得分:0)

这可能有点晚了,在线程模块中尝试“Event()”方法,然后使用信号模块及其方法来捕获信号。我会在下面留下一个链接,Miguel Grinberg 对此发表了一个简单明了的解释。

链接:https://blog.miguelgrinberg.com/post/how-to-kill-a-python-thread