Python blocked thread termination method? - python

I have a question in Python programming. I am writing a code that has a thread. This thread is a blocked thread. Blocked thread means: a thread is waiting for an event. If the event is not set, this thread must wait until the event is set. My expectation that block thread must wait the event without any timeout for waiting!
After starting the blocked thread, I write a forever loop to calculate a counter. The problem is: When I want to terminate my Python program by Ctrl+C, I can not terminate the blocked thread correctly. This thread is still alive! My code is here.
import threading
import time
def wait_for_event(e):
while True:
"""Wait for the event to be set before doing anything"""
e.wait()
e.clear()
print "In wait_for_event"
e = threading.Event()
t1 = threading.Thread(name='block',
target=wait_for_event,
args=(e,))
t1.start()
# Check t1 thread is alive or not
print "Before while True. t1 is alive: %s" % t1.is_alive()
counter = 0
while True:
try:
time.sleep(1)
counter = counter + 1
print "counter: %d " % counter
except KeyboardInterrupt:
print "In KeyboardInterrupt branch"
break
print "Out of while True"
# Check t1 thread is alive
print "After while True. t1 is alive: %s" % t1.is_alive()
Output:
$ python thread_test1.py
Before while True. t1 is alive: True
counter: 1
counter: 2
counter: 3
^CIn KeyboardInterrupt branch
Out of while True
After while True. t1 is alive: True
Could anyone give me a help? I want to ask 2 questions.
1. Can I stop a blocked thread by Ctrl+C? If I can, please give me a feasible direction.
2. If we stop the Python program by Ctrl+\ keyboard or reset the Hardware (example, PC) that is running the Python program, the blocked thread can be terminated or not?

Ctrl+C stops only the main thread, Your threads aren't in daemon mode, that's why they keep running, and that's what keeps the process alive. First make your threads to daemon.
t1 = threading.Thread(name='block',
target=wait_for_event,
args=(e,))
t1.daemon = True
t1.start()
Similarly for your other Threads. But there another problem - once the main thread has started your threads, there's nothing else for it to do. So it exits, and the threads are destroyed instantly. So let's keep the main thread alive:
import time
while True:
time.sleep(1)
Please have a look at this, I hope you will get your other answers.

If you need to kill all running python's processes you can simply run pkill python from the command line.
This is a little bit extreme but would work.
An other solution would be to use locking inside your code see here:

Related

How can I terminate a thread in Python3 after a specified timeout? [duplicate]

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.
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.
Is this approach valid, and is this the most pythonic way to go about my problem statement?
Here is some 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."
Using an Event in this case is works just fine as the signalling mechanism, and
is actually recommended in the threading module docs.
If you want your threads to stop gracefully, make them non-daemonic and use a
suitable signalling mechanism such as an Event.
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()
I'm way late to this game, but I've been wrestling with a similar question and the following appears to both resolve the issue perfectly for me AND lets me do some basic thread state checking and cleanup when the daemonized sub-thread exits:
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()
Yields:
0
1
KILL MAIN THREAD: 140013208254208
'CLEANLY' kill sub-thread with value: 2 [THREAD: 140013674317568]
I was also struggling to close a thread that was waiting to receive a notification.
Tried solution given here by user5737269 but it didn't really work for me. It was getting stuck in second join statement(without timeout one). Struggled a lot but didn't find any solution to this problem. Got this solution after thinking sometime:
My thread is waiting to receive a message in que. I want to close this thread, if no notification is received for 20 seconds. So, after 20 seconds, I am writing a message to this que so that thread terminates on its own.
Here's code:
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!!")
This worked for me.. Hope this idea helps someone!

Threading Process Waits For Input

I'm trying to run a background timer while running other processes. I've used thread.Thread:
import threading
import random
import time
import sys
def timer(limit):
time.sleep(limit)
sys.exit()
def code():
dictionary=['hello','loading','dumb']
word=[]
c=random.choice(dictionary)
answer=c
for x in c:
word.append(x)
y=0
words=''
while y!=len(c):
x=random.choice(word)
word.remove(x)
words=words+x
y+=1
print(words)
guess=input()
if guess==answer:
print('NOICE')
else:
print("NUB")
permit=input('Play Again?')
t1=threading.Thread(target=timer, args=(10,))
t2=threading.Thread(target=code)
t1.start()
t2.start()
That`s all my code. The problem is that when i run it, the timer waits for input before exiting. I want the timer to exit at ten second mark, whether or not input was entered. I thought that threading would make it so that the processes would not have to wait for each other. Help please?
Oh, and I'm only a few days into python, so please keep your explanations simple. Thanks.
When you call sys.exit() in one of your threads, this does not affect the other threads. That is simply the nature of them! All threads are equal.
If you want to make a thread that will terminate when the program exits, it needs to be made into a daemon (think a slave under the master thread).
To do that:
slave_thread.daemon = True
And in your case:
t2.daemon = True
Thus, t2 will be terminated when the main thread exits. Do not confuse this main thread with t1. The main thread will continue executing while there are threads running (t1). But as soon as t1 exits, t2 will be terminated, because it is a daemon.

Python Threading/Daemon

Self-taught programming student, so I apologize for all the amateur mistakes. I want to learn some deeper subjects, so I'm trying to understand threading, and exception handling.
import threading
import sys
from time import sleep
from random import randint as r
def waiter(n):
print "Starting thread " + str(n)
wait_time = r(1,10)
sleep(wait_time)
print "Exiting thread " + str(n)
if __name__=='__main__':
try:
for i in range(5):
t = threading.Thread(target=waiter, args=(i+1,))
t.daemon = True
t.start()
sleep(3)
print 'All threads complete!'
sys.exit(1)
except KeyboardInterrupt:
print ''
sys.exit(1)
This script just starts and stops threads after a random time and will kill the program if it receives a ^C. I've noticed that it doesn't print when some threads finish:
Starting thread 1
Starting thread 2
Starting thread 3
Exiting thread 3
Exiting thread 2
Starting thread 4
Exiting thread 1
Exiting thread 4
Starting thread 5
All threads complete!
In this example, it never states it exits thread 5. I find I can fix this if I comment out the t.daemon = True statement, but then exception handling waits for any threads to finish up.
Starting thread 1
Starting thread 2
^C
Exiting thread 1
Exiting thread 2
I can understand that when dealing with threads, it's best that they complete what they're handling before exiting, but I'm just curious as to why this is. I'd really appreciate any answers regarding the nature of threading and daemons to guide my understanding.
The whole point of a daemon thread is that if it's not finished by the time the main thread finishes, it gets summarily killed. Quoting the docs:
A thread can be flagged as a “daemon thread”. The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set through the daemon property or the daemon constructor argument.
Note Daemon threads are abruptly stopped at shutdown. Their resources (such as open files, database transactions, etc.) may not be released properly. If you want your threads to stop gracefully, make them non-daemonic and use a suitable signalling mechanism such as an Event.
Now, look at your logic. The main thread only sleeps for 3 seconds after starting thread 5. But thread 5 can sleep for anywhere from 1-10 seconds. So, about 70% of the time, it's not going to be finished by the time the main thread wakes up, prints "All threads complete!", and exits. But thread 5 is still asleep for another 5 seconds. In which case thread 5 will be killed without ever going to print "Exiting thread 5".
If this isn't the behavior you want—if you want the main thread to wait for all the threads to finish—then don't use daemon threads.

Python Threading - Managing thread termination and the main thread

Before you read on, know that I'm new to Python and very new to threading so forgive me if I misunderstand how threads work or make a rookie error :P
Short description of my goal:
The main thread (a) does some things (e.g. prints "begin!")
Main thread spawns a new thread (b) that first prints "Thread B
started" and then prints x+1 forever (1, 2, 3 ...)
Main thread prints "Woop!"
Then the end of the main thread is reached, it terminates itself and
then switches to thread b making b the main thread
Program is now running thread b as the main thread so is just
printing x+1 forever and a has been forgotten and is no longer
relevant
Ctrl+C will terminate thread b and effectively, the whole program
will be terminated because thread a doesn't exist anymore
Here's what I have so far (the basics):
import threading, time
def printCount():
print "Thread B started"
x = 0
while True:
time.sleep(1)
x = x + 1
print x
## User Code ##
print "begin!"
threadB = threading.Thread(target=printCount)
threadB.start()
print "woop!"
The requirements are:
I don't want to modify below the 'User Code' mark much at all. I
certainly don't want to wrap it in a class, a function or it's own
thread
Pressing Ctrl+C at any point should terminate the entire program
with no threads left running (Using something like: except
KeyboardInterrupt: os._exit(1)) inside User Code is fine
Thread a may continue to run instead of making thread b the main
thread, but in this case, I don't want the code to handle Ctrl+C
terminating the entire program inside the User Code section
This example is not my actual goal, just a simplified version of the problem I'm having. I'm trying to make an IRC framework where the user can import it and use the API very simply without messying their own code with threads and interrupts and the like. This is why it's important for the user code to be as clean as possible.
The framework would allow the user to create an IRC bot which runs forever, listening to commands whilst allowing the user to add their own commands. The Github link is here if you're interested (It's very WIP atm).
You cannot "switch" threads. So once you're done with your main thread, you have to wait for the other threads to terminate using the method join. But note this:
Since the join method is not interruptible with KeyboardInterrupt, you need to specify a timeout and loop over to detect user interrupts.
Since you can't force a thread to terminate, you have to implement a stop mecanism using threading.Event for instance
You also need to use threading.Lock to prevent concurrent access on shared resources, like sys.stdout (used when you print)
I gathered these aspects in a class called ThreadHandler, please have a look:
import threading, time
def printCount(lock, stop):
with lock:
print "Thread B started"
x = 0
while not stop.is_set():
time.sleep(1)
x = x + 1
with lock:
print x
class ThreadHandler():
STEP = 0.2
def __init__(self, target):
self.lock = threading.Lock()
self.stop = threading.Event()
args = (self.lock, self.stop)
self.thread = threading.Thread(target=target, args=args)
def start(self):
self.thread.start()
def join(self):
while self.thread.is_alive():
try:
self.thread.join(self.STEP)
except KeyboardInterrupt:
self.stop.set()
## User Code ##
print "begin!"
handler = ThreadHandler(target=printCount)
handler.start()
with handler.lock:
print "woop!"
handler.join()
Wrote a short note on another question yesterday having similar issues, this is a check you could implement in the subthread "b":
Instead of while 1: do the following:
def printCount():
main = None
for t in threading.enumerate():
if t.name == 'MainThread':
main = t
print "Thread B started"
x = 0
while main and main.isAlive():
time.sleep(1)
x = x + 1
print x
It would be a good idea to store main in the global scope for all threads to use isntead of having to look up the main thread each and every initation of the sub-thread.
But this would do the work in your example.
main will be the handle towards your main thread by iterating through all threads (.enumerate()) and then placing the thread called "MainThread" into main and then calling main.isAlive() to check if it's still running.
if main is None or False or if .isAlive() returns False it will indicate that the thread is either non-existant or dead, shutting down your subthread :)
You can't switch threads like that. It doesn't work like that.
However you could use signals with a global flag ALIVE:
import threading, time, signal
ALIVE = True
def handle_sigint(signum, frame):
global ALIVE
ALIVE = False
signal.signal(signal.SIGINT, handle_sigint)
def printCount():
print "Thread B started"
x = 0
while ALIVE: # <--- note the change
time.sleep(1)
x = x + 1
print x
## User Code ##
print "begin!"
threadB = threading.Thread(target=printCount)
threadB.start()
print "woop!"
signal.pause() # <--- wait for signals
Now it will gracefully quit after pressing CTRL+C.

In Python threading, how I can I track a thread's completion?

I've a python program that spawns a number of threads. These threads last anywhere between 2 seconds to 30 seconds. In the main thread I want to track whenever each thread completes and print a message. If I just sequentially .join() all threads and the first thread lasts 30 seconds and others complete much sooner, I wouldn't be able to print a message sooner -- all messages will be printed after 30 seconds.
Basically I want to block until any thread completes. As soon as a thread completes, print a message about it and go back to blocking if any other threads are still alive. If all threads are done then exit program.
One way I could think of is to have a queue that is passed to all the threads and block on queue.get(). Whenever a message is received from the queue, print it, check if any other threads are alive using threading.active_count() and if so, go back to blocking on queue.get(). This would work but here all the threads need to follow the discipline of sending a message to the queue before terminating.
I'm wonder if this is the conventional way of achieving this behavior or are there any other / better ways ?
Here's a variation on #detly's answer that lets you specify the messages from your main thread, instead of printing them from your target functions. This creates a wrapper function which calls your target and then prints a message before terminating. You could modify this to perform any kind of standard cleanup after each thread completes.
#!/usr/bin/python
import threading
import time
def target1():
time.sleep(0.1)
print "target1 running"
time.sleep(4)
def target2():
time.sleep(0.1)
print "target2 running"
time.sleep(2)
def launch_thread_with_message(target, message, args=[], kwargs={}):
def target_with_msg(*args, **kwargs):
target(*args, **kwargs)
print message
thread = threading.Thread(target=target_with_msg, args=args, kwargs=kwargs)
thread.start()
return thread
if __name__ == '__main__':
thread1 = launch_thread_with_message(target1, "finished target1")
thread2 = launch_thread_with_message(target2, "finished target2")
print "main: launched all threads"
thread1.join()
thread2.join()
print "main: finished all threads"
The thread needs to be checked using the Thread.is_alive() call.
Why not just have the threads themselves print a completion message, or call some other completion callback when done?
You can the just join these threads from your main program, so you'll see a bunch of completion messages and your program will terminate when they're all done, as required.
Here's a quick and simple demonstration:
#!/usr/bin/python
import threading
import time
def really_simple_callback(message):
"""
This is a really simple callback. `sys.stdout` already has a lock built-in,
so this is fine to do.
"""
print message
def threaded_target(sleeptime, callback):
"""
Target for the threads: sleep and call back with completion message.
"""
time.sleep(sleeptime)
callback("%s completed!" % threading.current_thread())
if __name__ == '__main__':
# Keep track of the threads we create
threads = []
# callback_when_done is effectively a function
callback_when_done = really_simple_callback
for idx in xrange(0, 10):
threads.append(
threading.Thread(
target=threaded_target,
name="Thread #%d" % idx,
args=(10 - idx, callback_when_done)
)
)
[t.start() for t in threads]
[t.join() for t in threads]
# Note that thread #0 runs for the longest, but we'll see its message first!
What I would suggest is loop like this
while len(threadSet) > 0:
time.sleep(1)
for thread in theadSet:
if not thread.isAlive()
print "Thread "+thread.getName()+" terminated"
threadSet.remove(thread)
There is a 1 second sleep, so there will be a slight delay between the thread termination and the message being printed. If you can live with this delay, then I think this is a simpler solution than the one you proposed in your question.
You can let the threads push their results into a threading.Queue. Have another thread wait on this queue and print the message as soon as a new item appears.
I'm not sure I see the problem with using:
threading.activeCount()
to track the number of threads that are still active?
Even if you don't know how many threads you're going to launch before starting it seems pretty easy to track. I usually generate thread collections via list comprehension then a simple comparison using activeCount to the list size can tell you how many have finished.
See here: http://docs.python.org/library/threading.html
Alternately, once you have your thread objects you can just use the .isAlive method within the thread objects to check.
I just checked by throwing this into a multithread program I have and it looks fine:
for thread in threadlist:
print(thread.isAlive())
Gives me a list of True/False as the threads turn on and off. So you should be able to do that and check for anything False in order to see if any thread is finished.
I use a slightly different technique because of the nature of the threads I used in my application. To illustrate, this is a fragment of a test-strap program I wrote to scaffold a barrier class for my threading class:
while threads:
finished = set(threads) - set(threading.enumerate())
while finished:
ttt = finished.pop()
threads.remove(ttt)
time.sleep(0.5)
Why do I do it this way? In my production code, I have a time limit, so the first line actually reads "while threads and time.time() < cutoff_time". If I reach the cut-off, I then have code to tell the threads to shut down.

Categories