【问题标题】:Python3 Let threads finish when keyboardexception raisedPython3在引发键盘异常时让线程完成
【发布时间】:2017-02-07 04:57:35
【问题描述】:

我正在寻找一种方法来让线程完成它们的工作,并且在 CTRL-C 被触发时不接受新的工作。 理论代码:

import threading
from Queue import Queue
q = Queue(maxsize=0)
def work(q):
    print (line)
for line in file_of_100_line:
    q.put(line)
nbThreads = 2
for i in range(nbThreads):
    t = threading.Thread(target=work, args=(q))
    t.setDaemon(True)
    t.start()

如果出现键盘异常 (CTRL-C),让工作人员打印该行,当所有工作人员完成当前任务时,退出。

【问题讨论】:

    标签: python multithreading exception keyboardinterrupt


    【解决方案1】:

    以下应该做你想要的:

    import signal
    import threading
    from time import sleep
    
    keep_running = True
    
    def signal_handler(signal, frame):
        global keep_running
        keep_running = False
        print("Received SIGINT\n")
    
    signal.signal(signal.SIGINT,signal_handler)
    
    def work():
        while keep_running:
            sleep(2)
        print("Worker finished\n")
    
    nbThreads = 2
    threads = []
    for i in range(nbThreads):
        t = threading.Thread(target=work)
        t.setDaemon(True)
        t.start()
        threads.append(t)
    
    while any([t.isAlive() for t in threads]):
        sleep(0.1)
    

    让这个程序运行产生

    Received SIGINT
    
    Worker finished
    Worker finished
    

    解释:当按下 CTRL-C 时,程序接收到一个 signal.SIGINT,这会导致注册的处理程序 signal_handler 被调用,将全局变量 keep_running 设置为 False。同时主线程等待所有派生的线程死亡。因此,这些线程可以在主线程终止之前完成它们正在做的任何事情(在本例中为 sleep-ing)。

    注意:在 Linux 上等待信号可以通过调用 signal.pause()(替换 sleep(0.1))来实现。在 Windows 上这是不可能的,因为此功能不存在。因此,上述内容应该较少依赖于平台。

    【讨论】:

    • 为了在运行时仍然打印“工人完成”,我要做的就是用“继续”替换最后一行,对吗?
    • 应该替换什么来让工作人员打印“工作人员完成”,当按下 ctrl+C 时,让他们完成......并退出?
    • 因为我希望函数 work() 在 ctrl+C 被击中之前运行。
    • 我真的读错了...明白了,最后一件事,你说用 continue 替换 sleep 会浪费 cpu 周期,但 sleep(0.1) 不会?我应该给睡眠功能更多的时间吗?例如:睡眠(2)
    • 这取决于您希望程序的响应速度。在所有线程完成后,程序最多可能需要最后一个 while 循环的主体实际完成所需的时间。因此,睡得更久更效率,但程序可能看起来没有响应。因此,我认为睡 1/10 秒是一个很好的权衡。
    猜你喜欢
    • 2018-09-08
    • 2020-03-11
    • 2022-07-17
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 2023-03-04
    相关资源
    最近更新 更多