Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在一段时间后杀死线程的最具python风格的方法_Python_Multithreading - Fatal编程技术网

在一段时间后杀死线程的最具python风格的方法

在一段时间后杀死线程的最具python风格的方法,python,multithreading,Python,Multithreading,我想在线程中运行一个进程(在大型数据库表上迭代)。线程运行时,我只希望程序等待。如果该线程花费的时间超过30秒,我想杀死该线程并执行其他操作。通过终止线程,我的意思是我希望它停止活动并优雅地释放资源 我认为最好的方法是通过Thread()的join(delay)和is_alive()函数以及事件来实现。使用join(delay)我可以让我的程序等待线程完成30秒,通过使用is\u alive()函数,我可以确定线程是否完成了它的工作。如果尚未完成其工作,则设置事件,线程知道在该点停止工作 这种方

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

我认为最好的方法是通过
Thread()
join(delay)
is_alive()
函数以及
事件来实现。使用
join(delay)
我可以让我的程序等待线程完成30秒,通过使用
is\u 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."

在这种情况下,使用事件与信令机制一样工作正常,并且 实际上是推荐的

如果希望线程正常停止,请将其设为非守护线程并使用 合适的信号机制,如
事件

在验证线程终止时,超时几乎总是为线程终止带来空间 错误。因此,在使用
.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()

在这种情况下,使用事件与信令机制一样工作正常,并且 实际上是推荐的

如果希望线程正常停止,请将其设为非守护线程并使用 合适的信号机制,如
事件

在验证线程终止时,超时几乎总是为线程终止带来空间 错误。因此,在使用
.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()

我玩这个游戏已经晚了很久,但我一直在努力解决这个问题,下面的内容似乎可以为我完美地解决这个问题,并让我在守护子线程退出时执行一些基本的线程状态检查和清理:

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]

我玩这个游戏已经晚了很久,但我一直在努力解决这个问题,下面的内容似乎可以为我完美地解决这个问题,并让我在守护子线程退出时执行一些基本的线程状态检查和清理:

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]

我还努力关闭一个等待接收通知的线程。 尝试了用户5737269在这里给出的解决方案,但对我来说并没有真正起作用。它卡在第二个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!!")

这对我很有用。。希望这个想法能帮助别人

我还在努力关闭一个等待接收通知的线程。 尝试了用户5737269在这里给出的解决方案,但对我来说并没有真正起作用。它卡在第二个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!!")

这对我很有用。。希望这个想法能帮助别人

这里是什么?它是如何与t相联系的?为了完整起见,请更新代码好吗?@SadıkYıldız
e=threading.Event()
这里的e是什么?它是如何与t相联系的?为了完整起见,您可以更新代码吗?@SadıkYıldız
e=threading.Event()