如何使用threading模块暂停和恢复线程?
我有一个很长的过程,我把它安排在一个线程里运行,因为如果不这样做的话,我的wxpython应用程序的界面会卡住。
我使用了:
threading.Thread(target=myLongProcess).start()
来启动这个线程,它是有效的,但我不知道怎么暂停和恢复这个线程。我查了Python的文档,但没找到相关的方法。
有没有人能建议我怎么做呢?
6 个回答
你可以使用信号来实现这个功能,具体可以参考这个链接:http://docs.python.org/library/signal.html#signal.pause
如果不想用信号的话,你可以考虑使用一种“令牌传递”的系统。如果你想从主界面线程暂停它,可以用一个 Queue.Queue 对象来进行沟通。
你只需要在队列里放一个消息,告诉线程要睡多久。
另外,你也可以从主界面线程不断地往队列里推送令牌。工作线程可以每隔 N 秒(比如 0.2 秒)检查一次队列。当队列里没有令牌可以取时,工作线程就会暂停。如果你想让它重新开始,只需从主线程继续往队列里推送令牌就可以了。
没有办法让其他线程强制暂停一个线程(就像也不能杀死那个线程一样)——目标线程必须配合,偶尔检查一些“标志”(比如可以用threading.Condition
来处理暂停和恢复的情况)。
如果你使用的是类Unix的系统(基本上就是除了Windows以外的系统),你可以用multiprocessing
来代替threading
——这个方法更强大,可以向“其他进程”发送信号;SIGSTOP信号会无条件地暂停一个进程,而SIGCONT信号则会让它继续运行(如果你的进程在暂停前需要做点事情,可以考虑使用SIGTSTP信号,其他进程可以捕捉到这个信号来执行一些暂停前的任务。虽然在Windows上可能也有类似的方法,但我对这些不太了解)。
我也做了一些速度测试,设置标志和执行动作的时间非常快,在一台慢的双处理器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)