The most Putin way to kill a stream after a certain period of time

I would like to start a process in a thread (which iterates over a large database table). While the thread is running, I just want the program to wait. If this thread takes more than 30 seconds, I want to kill the thread and do something else. Having killed the stream, I want to say that I want it to stop activity and release resources gracefully.

I decided that the best way to do this is through the Thread() join(delay) and is_alive() and Event functions. Using join(delay) , I can make the program wait 30 seconds to complete the stream, and using the is_alive() function I can determine if the stream has completed its work. If it has not completed its work, the event is set, and the thread knows that it stops working at this point.

Is this approach valid and is it the most pythonic way to solve my problem?

Here is a sample code:

 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." 
+8
source share
2 answers

Using the event in this case works fine as a signaling mechanism, and is actually recommended in the documents for the stream module .

If you want your threads to stop fading, make them non-demonic and use a suitable signaling mechanism such as Event .

When checking for stream termination, timeouts almost always introduce space for error. Therefore, using .join() with a timeout for the initial decision to trigger the event in order, the final check should be performed using .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 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 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() 
+4
source

I was late for this game, but I struggled with a similar question, and it seems to me that for me all this perfectly solves the problem. And it allows me to perform some basic checks on the state of the stream and clear them when exiting the demonized subflow:

 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() 

Productivity:

 0 1 KILL MAIN THREAD: 140013208254208 'CLEANLY' kill sub-thread with value: 2 [THREAD: 140013674317568] 
+1
source

All Articles