我想在一个线程中运行一个进程(它在一个大型数据库表上迭代)。当线程运行时,我只想让程序等待。如果该线程花费的时间超过30秒,我想杀死该线程并执行其他操作。通过终止线程,我的意思是我希望它停止活动并优雅地释放资源。
我认为最好的方法是通过Thread()的join(delay)和is_alive()函数,以及一个Event。使用join(delay),我可以让我的程序等待30秒,让线程完成,通过使用is_alive()函数,我可以确定线程是否已经完成了它的工作。如果它还没有完成它的工作,就设置事件,线程知道在这一点上停止工作。
这种方法是有效的吗,这是我的问题陈述最典型的方式吗?
下面是一些示例代码:
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."发布于 2016-01-02 13:49:36
在这种情况下,使用事件作为信令机制工作得很好,并且实际上在threading module docs中是推荐的。
如果你想让你的线程优雅地停止,让它们成为非守护进程,并使用合适的信号机制,比如
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()发布于 2018-05-23 02:44:44
我玩这个游戏太晚了,但我一直在努力使用a similar question,下面的方法似乎都完美地为我解决了这个问题,并让我在守护化子线程退出时执行一些基本的线程状态检查和清理:
import threading
import time
import atexit
def do_work():
i = 0
@atexit.register
def goodbye():
print ("'CLEANLY' kill sub-thread with value: %s [THREAD: %s]" %
(i, threading.currentThread().ident))
while True:
print i
i += 1
time.sleep(1)
t = threading.Thread(target=do_work)
t.daemon = True
t.start()
def after_timeout():
print "KILL MAIN THREAD: %s" % threading.currentThread().ident
raise SystemExit
threading.Timer(2, after_timeout).start()收益率:
0
1
KILL MAIN THREAD: 140013208254208
'CLEANLY' kill sub-thread with value: 2 [THREAD: 140013674317568]发布于 2019-12-11 14:59:20
我也在努力关闭一个等待接收通知的线程。尝试了user5737269在这里给出的解决方案,但它对我来说并不是真的有效。它在第二个join语句中卡住了(没有超时语句)。挣扎了很多,但没有找到任何解决这个问题的方法。经过思考后得到了这样的解决方案:我的线程正在等待接收que中的消息。如果在20秒内没有收到通知,我想关闭这个线程。所以,在20秒之后,我向这个que写了一条消息,这样线程就会自动终止。代码如下:
q = Queue.Queue()
t.join(20)
if t.is_alive():
print("STOPPING THIS THREAD ....")
q.put("NO NOTIFICATION RECEIVED")
t.join(20)
else:
print("Thread completed successfully!!")这对我很有效..希望这个想法能对某些人有所帮助!
https://stackoverflow.com/questions/34562473
复制相似问题