How can sleep forever in python? - python

I know that I can block the current thread with time.sleep(0xFFFFFFFFF) but is there other way?
I know that this may be seem silly, but there are use cases.
For example this could be used inside a try except to catch KeyboardInterrupt exception.
See this: https://stackoverflow.com/a/69744286/1951448
Or if there are daemonic threads running and there is nothing more to do, but don't want the threads be killed, then the main thread has to be suspended.
To clarify, I dont want to kill the thread, I want to suspend it.

It's unusual to want to block a thread indefinitely, so AFAIK there isn't an API designed specifically for that use case.
The simplest way to achieve that goal would be to call time.sleep() with a large value, as you suggested; wrap it in a while True: loop so that even if the specified time-period expires, your thread will wake up and then go immediately back to sleep again.
OTOH if for some reason you want to guarantee that your thread never wakes up at all, no matter how much time passes, you could have it call recv() on a socket that you are certain will never actually receive any data, e.g.:
import socket
print("About to sleep forever")
[sockA, sockB] = socket.socketpair()
junk = sockA.recv(1) # will never return since sockA will never receive any data
print("This should never get printed")

Related

How to terminate or kill a thread in Python

I would like to kill a thread in python upon certain events.
For example, I have a class within the class there is a neccessary function, for example this:
class exampleClass:
def neccessary_function(self):
try:
do_something()
return
except:
kill_this_thread()
I have multiple threads running simultaneously and I only want to kill that specific thread not all of them.
I can't return the function or anything like that, I need to either stop the thread doing anything or kill it. I currently have in the except section:
while True:
time.sleep(300)
But I feel as though that is not the best way to do it.
It is generally considered unsafe to kill a thread - it could still be holding onto some resources and can lead to deadlocks.
You can look at ways to kill a thread, although as long as you want to be safe, your options are just to "ask the thread kindly to stop when it's ready".
I would suggest you take a look at multiprocessing or asyncio - both APIs provide a rather simple way to cancel an async operation.

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.

Setting up idle thread/signalling thread

I'm using Python with wxPython for writing an app.
The method I'm considering to accomplish this may not be the best - if that's the case, let me know because I'm open to refactoring.
Right now, I have one GUI form. The main program start point instantiates an instance of the GUI form then runs wx.mainLoop(), which causes the app's main initial thread to block for the lifetime of the app.
We of course know that when events happen in the UI, the UI thread runs the code for them.
Now, I have another thread - a worker thread. This thread needs to sit idle, and then when something happens in the UI thread, e.g. a button is clicked, I want the worker thread to stop idling and do something else - run a function, say.
I can't envision this right now but I could see as the app gets more complex also having to signal the worker thread while it's actually busy doing something.
I have two questions about this setup:
How can I make my worker thread idle without using up CPU time? Doing something like while True: pass will suck CPU time, while something like while True: time.sleep(0.1) will not allow instantaneous reaction to events.
What's the best way to signal into the worker thread to do something? I don't want the UI thread to execute something, I want the worker thread to be signaled, by the UI thread, that it should change what it's doing. Ideally, I'd have some way for the worker thread to register a callback with the UI itself, so that when a button is clicked or any other UI Event happens, the worker thread is signalled to change what it's doing.
So, is this the best way to accomplish this? And what's the best way to do it?
Thanks!
First: Do you actually need a background thread to sit around idle in the first place?
On most platforms, starting a new thread is cheap. (Except on Windows and Linux, where it's supercheap.) So, why not just kick off a thread whenever you need it? (It's just as easy to keep around a list of threads as a single thread, right?)
Alternatively, why not just create a ThreadPoolExecutor, and just submit jobs to it, and let the executor worry about when they get run and on which thread. Any time you can just think in terms of "tasks that need to get run without blocking the main thread" instead of "worker threads that need to wait on work", you're making your life easier. Under the covers, there's still one or more worker threads waiting on a queue, or something equivalent, but that part's all been written (and debugged and optimized) for you. All you have to write are the tasks, which are just regular functions.
But, if you want to write explicit background threads, you can, so I'll explain that.
How can I make my worker thread idle without using up CPU time? … What's the best way to signal into the worker thread to do something?
The way to idle a thread until a value is ready is to wait on a synchronization object. On any modern OS, waiting on a synchronization object means the operating system stops giving you any CPU time until the object is ready for you.*
There are a variety of different options you can see in the Threading module docs, but the obvious one to use in most cases like this is a Condition. The way to signal the worker thread is then to notify the Condition.
However, often a Queue is a lot simpler. To wait on a Queue, just call its get method with block=True. To signal another thread to wake up, just put something on the Queue. (Under the covers, a Queue wraps up a list or deque or other collection, a Lock, and a Condition, so you just tell it what you want to do—check for a value, block until there's a value, add a value—instead of dealing with waiting and signaling and protecting the collection.)
See the answer to controlling UI elements in wxPython using threading for how to signal in both directions, from a worker thread to a UI thread and vice-versa.
I'd have some way for the worker thread to register a callback with the UI itself, so that when a button is clicked or any other UI Event happens, the worker thread is signalled to change what it's doing.
You can do it this way if you want. Just pass self.queue.put or def callback(value): self.value = value; self.condition.notify() or whatever as a callback, and the GUI thread doesn't even have to know that the callback is triggering another thread.
In fact, that's a pretty nice design that may make you very happy later, when you decide to move some code back and forth between inline and background-threaded, or move it off to a child process instead of a background thread, or whatever.
I can't envision this right now but I could see as the app gets more complex also having to signal the worker thread while it's actually busy doing something.
But what do you want to happen if it's busy?
If you just want to say "If you're idle, wake up and do this task; otherwise, hold onto it and do it whenever you're ready", that's exactly what a Queue, or an Executor, will do for you automatically.
If you want to say, "If you're idle, wake up, otherwise, don't worry about it", that's what a Condition or Event will do.
If you want to say, "If you're idle, wake up and do this, otherwise, cancel what you're doing and do this instead", that's a bit more complicated. You pretty much need to have the background thread periodically check an "interrupt_me" variable while it's busy (and put a Lock around it), and then you'll set that flag as well as notifying the Condition… although in some cases, you can merge the idle and busy cases into a single Condition or Event (by calling an infinite wait() when idle, and a quick-check wait(timeout=0) when busy).
* In some cases—e.g., a Linux futex or a Windows CriticalSection—it may actually spin off a little bit of CPU time in some cases, because that happens to be a good optimization. But the point is, you're not asking for any CPU time until you're ready to use it.

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.

Categories

Resources