How to break an iteration on file lines in a thread - python

I have a reading thread in my application that listens on stdin. It blocks until some input is available. When some arrive, it accepts the lines, checks if they are valid commands and put them in a queue.
def ReadCommands( queue ):
for cmd in stdin:
if cmd=="":
break
# Check if cmd is valid and add to queue
queue = Queue()
thread = Thread( target=ReadCommands, args=( queue, ) )
thread.start()
Now when the main program wants to exit, it first has to join on this reading thread. The problem is that the thread is in a loop I have no control over. Even stdin.close() does not work.
How can I break the for loop in the reading thread from the main?
Alternatively, how can I write the for loop (with a while?) to be able to add my own boolean variable that would break the loop? Beware that I don't want an active waiting loop!

If you have threads that you just want to shut down on exiting your program, starting them in daemon mode is often the best way to go. If all non-daemon threads exit, your application will end, taking all daemon threads with it.
Note that you should only do this for threads that do not have to perform cleanup; your example seems to be fine for this.
Also, if you are performing a blocking C-level operation, a daemon thread may still block until it returns to the actual python scope. In that case, there is no python level option to break the block to begin with. Reading from broken sockets can be such an issue, for example.
If you need to explicitly kill a blocking thread before stopping your program, you will probably have to use the python's C-API. This can be implemented more cleanly but works in principle.

Related

Clean up a thread without .join() and without blocking the main thread

I am in a situation where I have two endpoints I can ask for a value, and one may be faster than the other. The calls to the endpoints are blocking. I want to wait for one to complete and take that result without waiting for the other to complete.
My solution was to issue the requests in separate threads and have those threads set a flag to true when they complete. In the main thread, I continuously check the flags (I know it is a busy wait, but that is not my primary concern right now) and when one completes it takes that value and returns it as the result.
The issue I have is that I never clean up the other thread. I can't find any way to do it without using .join(), which would just block and defeat the purpose of this whole thing. So, how can I clean up that other, slower thread that is blocking without joining it from the main thread?
What you want is to make your threads daemons, so when you get the result and finish your main, the other running thread will be forced to finish. You do that by changing the daemon keyword to True:
tr = threading.Thread(daemon=True)
From the threading docs:
The significance of this flag is that the entire Python program exits
when only daemon threads are left.
Although:
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.
I don't have any particular experience with Events so can't elaborate on that. Feel free to click the link and read on.
One bad and dirty solution is to implement a methode for the threads which close the socket which is blocking. Now you have to catch the exception in the main thread.

python function not running as thread

this is done in python 2.7.12
serialHelper is a class module arround python serial and this code does work nicely
#!/usr/bin/env python
import threading
from time import sleep
import serialHelper
sh = serialHelper.SerialHelper()
def serialGetter():
h = 0
while True:
h = h + 1
s_resp = sh.getResponse()
print ('response ' + s_resp)
sleep(3)
if __name__ == '__main__':
try:
t = threading.Thread(target=sh.serialReader)
t.setDaemon(True)
t.start()
serialGetter()
#tSR = threading.Thread(target=serialGetter)
#tSR.setDaemon(True)
#tSR.start()
except Exception as e:
print (e)
however the attemp to run serialGetter as thread as remarked it just dies.
Any reason why that function can not run as thread ?
Quoting from the Python documentation:
The entire Python program exits when no alive non-daemon threads are left.
So if you setDaemon(True) every new thread and then exit the main thread (by falling off the end of the script), the whole program will exit immediately. This kills all of the threads. Either don't use setDaemon(True), or don't exit the main thread without first calling join() on all of the threads you want to wait for.
Stepping back for a moment, it may help to think about the intended use case of a daemon thread. In Unix, a daemon is a process that runs in the background and (typically) serves requests or performs operations, either on behalf of remote clients over the network or local processes. The same basic idea applies to daemon threads:
You launch the daemon thread with some kind of work queue.
When you need some work done on the thread, you hand it a work object.
When you want the result of that work, you use an event or a future to wait for it to complete.
After requesting some work, you always eventually wait for it to complete, or perhaps cancel it (if your worker protocol supports cancellation).
You don't have to clean up the daemon thread at program termination. It just quietly goes away when there are no other threads left.
The problem is step (4). If you forget about some work object, and exit the app without waiting for it to complete, the work may get interrupted. Daemon threads don't gracefully shut down, so you could leave the outside world in an inconsistent state (e.g. an incomplete database transaction, a file that never got closed, etc.). It's often better to use a regular thread, and replace step (5) with an explicit "Finish up your work and shut down" work object that the main thread hands to the worker thread before exiting. The worker thread then recognizes this object, stops waiting on the work queue, and terminates itself once it's no longer doing anything else. This is slightly more up-front work, but is much safer in the event that a work object is inadvertently abandoned.
Because of all of the above, I recommend not using daemon threads unless you have a strong reason for them.

Interrupting Python raw_input() in a child thread with ^C/KeyboardInterrupt

In a multithreaded Python program, one thread sometimes asks for console input using the built-in raw_input(). I'd like to be able to be able to close the program while at a raw_input prompt by typing ^C at the shell (i.e., with a SIGINT signal). However, when the child thread is executing raw_input, typing ^C does nothing -- the KeyboardInterrupt is not raised until I hit return (leaving raw_input).
For example, in the following program:
import threading
class T(threading.Thread):
def run(self):
x = raw_input()
print x
if __name__ == '__main__':
t = T()
t.start()
t.join()
Typing ^C does nothing until after the input is finished. However, if we just call T().run() (i.e., the single-threaded case: just run raw_input in the main thread), ^C closes the program immediately.
Presumably, this is because SIGINT is sent to the main thread, which is suspended (waiting for the GIL) while the forked thread blocks on the console read. The main thread does not get to execute its signal handler until it grabs the GIL after raw_input returns. (Please correct me if I'm wrong about this -- I'm not an expert on Python's threading implementation.)
Is there a way to read from stdin in a raw_input-like way while allowing the SIGINT to be handled by the main thread and thus bring down the whole process?
[I've observed the behavior above on Mac OS X and a few different Linuxes.]
Edit: I've mischaracterized the underlying problem above. On further investigation, it's the main thread's call to join() that's preventing signal handling: Guido van Rossum himself has explained that the underlying lock acquire in join is uninterruptible. This means that the signal is actually being deferred until the entire thread finishes -- so this really has nothing to do with raw_input at all (just the fact that the background thread is blocking so that the join does not complete).
When join is called with no timeout, it is uninterruptable, but when it is called with a timeout, it is interruptable. Try adding an arbitrary timeout and putting it in a while loop:
while my_thread.isAlive():
my_thread.join(5.0)
There is really no easy way around this, period.
One approach is to reorganize and break up your code in a way that parts of functions which need Ctrl-C interruptibility are executed on the main thread. You use queues to send execution requests and likewise for the result values. You need one input queue for the main thread, and one output queue per non-main thread; and a coordinated main thread exit. Obviously, only one blocking function is executed at any given time this way, which may not be what you want.
Here's a working example of this idea with slightly perverse use of semaphores for the coordinated main thread exit.

Gracefully Terminating Python Threads

I am trying to write a unix client program that is listening to a socket, stdin, and reading from file descriptors. I assign each of these tasks to an individual thread and have them successfully communicating with the "main" application using synchronized queues and a semaphore. The problem is that when I want to shutdown these child threads they are all blocking on input. Also, the threads cannot register signal handlers in the threads because in Python only the main thread of execution is allowed to do so.
Any suggestions?
There is no good way to work around this, especially when the thread is blocking.
I had a similar issue ( Python: How to terminate a blocking thread) and the only way I was able to stop my threads was to close the underlying connection. Which resulted in the thread that was blocking to raise and exception and then allowed me to check the stop flag and close.
Example code:
class Example(object):
def __init__(self):
self.stop = threading.Event()
self.connection = Connection()
self.mythread = Thread(target=self.dowork)
self.mythread.start()
def dowork(self):
while(not self.stop.is_set()):
try:
blockingcall()
except CommunicationException:
pass
def terminate():
self.stop.set()
self.connection.close()
self.mythread.join()
Another thing to note is commonly blocking operations generally offer up a timeout. If you have that option I would consider using it. My last comment is that you could always set the thread to deamonic,
From the pydoc :
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.
Also, the threads cannot register signal handlers
Signals to kill threads is potentially horrible, especially in C, especially if you allocate memory as part of the thread, since it won't be freed when that particular thread dies (as it belongs to the heap of the process). There is no garbage collection in C, so if that pointer goes out of scope, it's gone out of scope, the memory remains allocated. So just be careful with that one - only do it that way in C if you're going to actually kill all the threads and end the process so that the memory is handed back to the OS - adding and removing threads from a threadpool for example will give you a memory leak.
The problem is that when I want to shutdown these child threads they are all blocking on input.
Funnily enough I've been fighting with the same thing recently. The solution is literally don't make blocking calls without a timeout. So, for example, what you want ideally is:
def threadfunc(running):
while running:
blockingcall(timeout=1)
where running is passed from the controlling thread - I've never used threading but I have used multiprocessing and with this you actually need to pass an Event() object and check is_set(). But you asked for design patterns, that's the basic idea.
Then, when you want this thread to end, you run:
running.clear()
mythread.join()
and your main thread should then allow your client thread to handle its last call, and return, and the whole program folds up nicely.
What do you do if you have a blocking call without a timeout? Use the asynchronous option, and sleep (as in call whatever method you have to suspend the thread for a period of time so you're not spinning) if you need to. There's no other way around it.
See these answers:
Python SocketServer
How to exit a multithreaded program?
Basically, don't block on recv() by using select() with a timeout to check for readability of the socket, and poll a quit flag when select() times out.

How to terminate a thread when main program ends?

If I have a thread in an infinite loop, is there a way to terminate it when the main program ends (for example, when I press Ctrl+C)?
If you make your worker threads daemon threads, they will die when all your non-daemon threads (e.g. the main thread) have exited.
http://docs.python.org/library/threading.html#threading.Thread.daemon
Check this question. The correct answer has great explanation on how to terminate threads the right way:
Is there any way to kill a Thread in Python?
To make the thread stop on Keyboard Interrupt signal (ctrl+c) you can catch the exception "KeyboardInterrupt" and cleanup before exiting. Like this:
try:
start_thread()
except (KeyboardInterrupt, SystemExit):
cleanup_stop_thread()
sys.exit()
This way you can control what to do whenever the program is abruptly terminated.
You can also use the built-in signal module that lets you setup signal handlers (in your specific case the SIGINT signal): http://docs.python.org/library/signal.html
Try to enable the sub-thread as daemon-thread.
Recommended:
from threading import Thread
t = Thread(target=desired_method)
t.daemon = True # Dies when main thread (only non-daemon thread) exits.
t.start()
Inline:
t = Thread(target=desired_method, daemon=True).start()
Old API:
t.setDaemon(True)
t.start()
When your main thread terminates (e.g. Ctrl+C keystrokes), other threads will also be killed by the instructions above.
Use the atexit module of Python's standard library to register "termination" functions that get called (on the main thread) on any reasonably "clean" termination of the main thread, including an uncaught exception such as KeyboardInterrupt. Such termination functions may (though inevitably in the main thread!) call any stop function you require; together with the possibility of setting a thread as daemon, that gives you the tools to properly design the system functionality you need.
If you spawn a Thread like so - myThread = Thread(target = function) - and then do myThread.start(); myThread.join(). When CTRL-C is initiated, the main thread doesn't exit because it is waiting on that blocking myThread.join() call. To fix this, simply put in a timeout on the .join() call. The timeout can be as long as you wish. If you want it to wait indefinitely, just put in a really long timeout, like 99999. It's also good practice to do myThread.daemon = True so all the threads exit when the main thread(non-daemon) exits.
Daemon threads are killed ungracefully so any finalizer instructions are not executed.
A possible solution is to check is main thread is alive instead of infinite loop.
E.g. for Python 3:
while threading.main_thread().isAlive():
do.you.subthread.thing()
gracefully.close.the.thread()
See Check if the Main Thread is still alive from another thread.

Categories

Resources