【问题标题】:How to stop child threads if keyboard exception occurs in python?如果python中发生键盘异常,如何停止子线程?
【发布时间】:2019-09-03 09:50:20
【问题描述】:

我遇到了线程概念的问题,即我有一个函数可以创建 10 个线程来执行任务。如果发生任何键盘中断,那些创建的线程仍在执行,我想停止这些线程并恢复更改。

以下代码片段是示例方法:

def store_to_db(self,keys_size,master_key,action_flag,key_status):
    for iteration in range(10):
        t = threading.Thread(target=self.store_worker, args=())
        t.start()
        threads.append(t)
    for t in threads:
        t.join()

def store_worker():
    print "DOING"

【问题讨论】:

    标签: multithreading python-2.7 keyboardinterrupt


    【解决方案1】:

    完成这项工作的想法是:

    • 您需要一个“线程池”,其中线程检查其do_run 属性是否为假。
    • 您需要该池外的“哨兵线程”检查池中的线程状态并根据需要调整“线程池”线程的do_run 属性。

    示例代码:

    import threading
    import random
    import time
    import msvcrt as ms
    
    
    def main_logic():
        # take 10 worker threads
        threads = []
        for i in range(10):
            t = threading.Thread(target=lengthy_process_with_brake, args=(i,))
            # start and append
            t.start()
            threads.append(t)
    
        # start the thread which allows you to stop all threads defined above
        s = threading.Thread(target=sentinel, args=(threads,))
        s.start()
    
        # join worker threads
        for t in threads:
            t.join()
    
    
    def sentinel(threads):
        # this one runs until threads defined in "threads" are running or keyboard is pressed
        while True:
            # number of threads are running
            running = [x for x in threads if x.isAlive()]
    
            # if kb is pressed
            if ms.kbhit():
                # tell threads to stop
                for t in running:
                    t.do_run = False
            # if all threads stopped, exit the loop
            if not running:
                break
    
            # you don't want a high cpu load for nothing
            time.sleep(0.05)
    
    
    def lengthy_process_with_brake(worker_id):
        # grab current thread
        t = threading.currentThread()
    
        # start msg
        print(f"{worker_id} STARTED")
    
        # exit condition
        zzz = random.random() * 20
        stop_time = time.time() + zzz
    
        # imagine an iteration here like "for item in items:"  
        while time.time() < stop_time:
    
            # the brake
            if not getattr(t, "do_run", True):
                print(f"{worker_id} IS ESCAPING")
                return
    
            # the task
            time.sleep(0.03)
    
        # exit msg
        print(f"{worker_id} DONE")
    
        # exit msg
        print(f"{worker_id} DONE")
    
    
    
    main_logic()
    

    此解决方案不会“杀死”线程,只是告诉它们停止迭代或执行任何操作。

    编辑: 我刚刚注意到“键盘异常”在标题中,而不是“任何键”。键盘异常处理有点不同,here is a good solution 为此。要点几乎相同:如果满足条件,您告诉线程返回。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-13
      • 2020-01-28
      • 2016-05-30
      • 1970-01-01
      • 2022-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多