如何通过ctrl + c停止多线程进程

时间:2014-04-15 03:48:54

标签: multithreading python-2.7

我正在尝试在执行期间终止进程,但它无法阻止它。

我的线程是无限循环线程,直到收到kill信号才会终止

enter image description here

我只能通过终端

上的kill命令终止
def signal_handler(*args):
    print("Killed by user")
    teardown()
    sys.exit(0)

def install_signal():
    for sig in (SIGABRT, SIGILL, SIGINT, SIGSEGV, SIGTERM):
        signal(sig, signal_handler)


class Monitor(object):
    ...
    def run(self):
        """Run the monitor thread

        Add the tasks to threads list
        """
        try:
            threads = {
                "streaming": Streaming(
                    self.args["rtsp_link"], 
                    int(self.args["duration"]), 
                    int(self.args["period"])
                ),
                "telnet_vid": p,
                "telnet_aud": c,
            }

            for sub_task in threads.values():
                sub_task.setDaemon(True)
                sub_task.start()

            for sub_task in threads.values():
                sub_task.join()

            time.sleep(1)

            logging.info("Completed Monitor Tasks")

        except KeyboardInterrupt:
            print("Ok ok, quitting")
            sys.exit(1)
        except BaseException as e:
            print("Got BaseException")
            traceback.print_exc(file=sys.stdout)
            raise e

def main():
    try:
        install_signal()
        monitor = Monitor('tests/test_configuration.txt')
        monitor.run()
    except KeyboardInterrupt:
        print("Ok ok, quitting")
        sys.exit(1)

如果我向join()添加超时,主线程将不会被阻止,将在几秒钟内终止并且不再能够接收键盘中断

我提到了这个blog

while len(running_threads) > 0 :
    try:
        print("To add join")
        # Join all threads using a timeout so it doesn't block
        # Filter out threads which have been joined or are None
        running_threads = [t.join(1) for t in running_threads if t is not None and t.isAlive()]
    except KeyboardInterrupt:
        print("Ctrl+C received! Sending kill to threads!!!")
        for t in running_threads:
            t.kill_received = True

1 个答案:

答案 0 :(得分:0)

替换:

for sub_task in threads.values():
    sub_task.join() # no timeout

使用:

running_threads = threads.values()
while running_threads:
    for t in running_threads:
        t.join(.1) # with timeout
    running_threads = [t for t in running_threads if t.is_alive()]