我想在线程中运行一个进程(它正在迭代一个大型数据库表)。当线程运行时,我只想让程序等待。如果该线程花费的时间超过 30 秒,我想终止该线程并执行其他操作。通过终止线程,我的意思是我希望它停止活动并优雅地释放资源。
我认为最好的方法是通过Thread()
's join(delay)
and is_alive()
功能,以及Event
。使用join(delay)
我可以让我的程序等待 30 秒让线程完成,并使用is_alive()
函数我可以确定线程是否已完成其工作。如果它尚未完成其工作,则会设置事件,并且线程知道此时停止工作。
这种方法是否有效,这是解决我的问题陈述的最Pythonic的方法吗?
这是一些示例代码:
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."
在这种情况下使用事件作为信号机制就可以很好地工作,并且
实际上是推荐的线程模块文档 https://docs.python.org/2/library/threading.html#module-threading.
如果您希望线程正常停止,请将它们设置为非守护线程并使用
合适的信号机制,例如Event
.
当验证线程终止时,超时几乎总是会带来空间
错误。因此,在使用时.join()
初始超时
触发事件的决定很好,最终验证应该使用.join()
没有超时。
# 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()
这可以简化为这样:
# 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()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)