如何使用threading模块暂停和恢复线程?

30 投票
6 回答
60620 浏览
提问于 2025-04-16 01:23

我有一个很长的过程,我把它安排在一个线程里运行,因为如果不这样做的话,我的wxpython应用程序的界面会卡住。

我使用了:

threading.Thread(target=myLongProcess).start()

来启动这个线程,它是有效的,但我不知道怎么暂停和恢复这个线程。我查了Python的文档,但没找到相关的方法。

有没有人能建议我怎么做呢?

6 个回答

4

你可以使用信号来实现这个功能,具体可以参考这个链接:http://docs.python.org/library/signal.html#signal.pause

如果不想用信号的话,你可以考虑使用一种“令牌传递”的系统。如果你想从主界面线程暂停它,可以用一个 Queue.Queue 对象来进行沟通。

你只需要在队列里放一个消息,告诉线程要睡多久。

另外,你也可以从主界面线程不断地往队列里推送令牌。工作线程可以每隔 N 秒(比如 0.2 秒)检查一次队列。当队列里没有令牌可以取时,工作线程就会暂停。如果你想让它重新开始,只需从主线程继续往队列里推送令牌就可以了。

10

没有办法让其他线程强制暂停一个线程(就像也不能杀死那个线程一样)——目标线程必须配合,偶尔检查一些“标志”(比如可以用threading.Condition来处理暂停和恢复的情况)。

如果你使用的是类Unix的系统(基本上就是除了Windows以外的系统),你可以用multiprocessing来代替threading——这个方法更强大,可以向“其他进程”发送信号;SIGSTOP信号会无条件地暂停一个进程,而SIGCONT信号则会让它继续运行(如果你的进程在暂停前需要做点事情,可以考虑使用SIGTSTP信号,其他进程可以捕捉到这个信号来执行一些暂停前的任务。虽然在Windows上可能也有类似的方法,但我对这些不太了解)。

29

我也做了一些速度测试,设置标志和执行动作的时间非常快,在一台慢的双处理器Linux电脑上只需要0.00002秒。

下面是一个使用 set()clear() 事件进行线程暂停测试的例子:

import threading
import time

# This function gets called by our thread.. so it basically becomes the thread init...                
def wait_for_event(e):
    while True:
        print('\tTHREAD: This is the thread speaking, we are Waiting for event to start..')
        event_is_set = e.wait()
        print('\tTHREAD:  WHOOOOOO HOOOO WE GOT A SIGNAL  : %s' % event_is_set)
        # or for Python >= 3.6
        # print(f'\tTHREAD:  WHOOOOOO HOOOO WE GOT A SIGNAL  : {event_is_set}')
        e.clear()

# Main code
e = threading.Event()
t = threading.Thread(name='pausable_thread', 
                     target=wait_for_event,
                     args=(e,))
t.start()

while True:
    print('MAIN LOOP: still in the main loop..')
    time.sleep(4)
    print('MAIN LOOP: I just set the flag..')
    e.set()
    print('MAIN LOOP: now Im gonna do some processing')
    time.sleep(4)
    print('MAIN LOOP:  .. some more processing im doing   yeahhhh')
    time.sleep(4)
    print('MAIN LOOP: ok ready, soon we will repeat the loop..')
    time.sleep(2)

撰写回答