一段时间后杀死线程的大多数Python方法 [英] Most Pythonic way to kill a thread after some period of time

查看:72
本文介绍了一段时间后杀死线程的大多数Python方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在一个线程中运行一个进程(正在对一个大的数据库表进行迭代).在线程运行时,我只希望程序等待.如果该线程花费的时间超过30秒,那么我想终止该线程并执行其他操作.通过杀死线程,我的意思是我希望它停止活动并优雅地释放资源.

I would like to run a process in a thread (which is iterating over a large database table). While the thread is running, I just want the program to wait. If that thread takes longer then 30 seconds, I want to kill the thread and do something else. By killing the thread, I mean that I want it to cease activity and release resources gracefully.

我认为最好的方法是通过Thread()join(delay)is_alive()函数,以及Event.使用join(delay),我可以让程序等待30秒以使线程完成,而通过使用is_alive()函数,我可以确定线程是否已完成其工作.如果尚未完成工作,则设置事件,并且线程知道在该点停止工作.

I figured the best way to do this was through a Thread()'s join(delay) and is_alive() functions, and an Event. Using the join(delay) I can have my program wait 30 seconds for the thread to finish, and by using the is_alive() function I can determine if the thread has finished its work. If it hasn't finished its work, the event is set, and the thread knows to stop working at that point.

这种方法有效吗,这是解决我的问题陈述的最Python方式吗?

Is this approach valid, and is this the most pythonic way to go about my problem statement?

以下是一些示例代码:

import threading
import time

# The worker loops for about 1 minute adding numbers to a set
# unless the event is set, at which point it breaks the loop and terminates
def worker(e):
    data = set()
    for i in range(60):
        data.add(i)
        if not e.isSet():
            print "foo"
            time.sleep(1)
        else:
            print "bar"
            break

e = threading.Event()
t = threading.Thread(target=worker, args=(e,))
t.start()

# wait 30 seconds for the thread to finish its work
t.join(30)
if t.is_alive():
    print "thread is not done, setting event to kill thread."
    e.set()
else:
    print "thread has already finished."

推荐答案

在这种情况下,使用事件作为信号传递机制就可以了,并且 实际上是在线程模块文档中推荐的.

Using an Event in this case is works just fine as the signalling mechanism, and is actually recommended in the threading module docs.

如果您希望线程正常停止,请使其成为非守护进程,并使用 合适的信令机制,例如Event.

If you want your threads to stop gracefully, make them non-daemonic and use a suitable signalling mechanism such as an Event.

在验证线程终止时,超时几乎总是会为 错误.因此,在将.join()与初始超时一起使用时 决定触发事件的决定是正确的,应使用以下命令进行最终验证: .join()没有超时.

When verifying thread termination, timeouts almost always introduce room for error. Therefore, while using the .join() with a timeout for the initial decision to trigger the event is fine, final verification should be made using a .join() without a timeout.

# wait 30 seconds for the thread to finish its work
t.join(30)
if t.is_alive():
    print "thread is not done, setting event to kill thread."
    e.set()
    # The thread can still be running at this point. For example, if the 
    # thread's call to isSet() returns right before this call to set(), then
    # the thread will still perform the full 1 second sleep and the rest of 
    # the loop before finally stopping.
else:
    print "thread has already finished."

# Thread can still be alive at this point. Do another join without a timeout 
# to verify thread shutdown.
t.join()

这可以简化为以下形式:

This can be simplified to something like this:

# Wait for at most 30 seconds for the thread to complete.
t.join(30)

# Always signal the event. Whether the thread has already finished or not, 
# the result will be the same.
e.set()

# Now join without a timeout knowing that the thread is either already 
# finished or will finish "soon."
t.join()

这篇关于一段时间后杀死线程的大多数Python方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆