how did monkey.patch_all() works? - python

the monkey.path_all() start a new thread is slowly, need around 20s. Could I set up the time?

Related

Which is more efficient? threading.Thread vs threading.Timer

This is more out of theoretical curiosity than an actual problem I am having.
Say you want to run some code at a regular interval, what are the pros and cons of using a Timer vs using a thread + time.sleep in terms of CPU consumption?
The two below approaches do the same. I am aware that the Thread approach is not exactly one second interval, but rather adds a delay after each execution, which can matter if the task_function operation takes a long time. I am also aware that there are many other ways to solve this problem, but lets focus on the threading package.
Timer approach
def task_function():
print(time.time())
def task():
task_function()
threading.Timer(1,task).start()
task()
Thread approach
def task_function():
while True:
print(time.time())
time.sleep(1)
threading.Thread(target=task_function).start()
I read somewhere that starting a thread is quite resource intensive. So I wonder that if you had some code you wanted to run every 0.1 seconds, would the Timer approach not be sub-optimal since a new thread has to be started so often?
If the code must repeat on an interval, use the plain Thread (to be clear, Timer is just a thin wrapper around a Thread in the first place; it's implemented as a subclass). Spawning a new thread (via Timer) 10x a second is wasteful, and gains you nothing in any event.
You should make the worker thread a daemon thread though, unless you really want it to keep the process alive indefinitely.

Having trouble with sleep.time, is there an alternative

I'm writing a program to control GPIO's on my raspberry pi. I would like my program to ask me how long I would like to keep a GPIO on before it turns off.
Is it possible to have it stay on for 1 hour and then turn off. The problem I'm having is that when its on for an hour I cant issue any other commands to turn on other GPIO's because sleep.time is still being processed. I'd like to set multiple GPIO's for different times at the same time.
There are many ways to solve the problem. Conceptually, instead of sleeping 30 seconds and then doing something, you can sleep one second, do a bunch of stuff, check the time, lather, rinse, repeat. And by "sleep one second" it could just as easily be a tenth of a second or five seconds or whatever seems reasonable to me.
Another solution is to create a second thread (or process) for this sleep command so that your main thread (or process) runs unabated.
The choice depends on what all you need to do, how accurate you need the delay to be, what other things are running on the system, and so on.
Your current script only have one thread running, the sleep() will put the current running thread into sleep mode which blocks further commands.
time.sleep(secs) Python Doc
time.sleep(secs)
Suspend execution of the current thread for the given number of seconds.
You will need one more thread on the background which keeps the timer for you. In the mean time, the thread on the foreground can still takes other commands.
I recommend you read this page
threading – Manage concurrent threads

Python - Stopping a long running taskq's thread

I have a fairly simple program that each task added into the taskq is executing and computing something, say for 30 seconds. This task is 'not' running in some kind of while or for loop.
def run(self):
while not self.stopper.is_set():
DO_MY_30_SECONDS_WORK(self)
self.task_done()
Now, assuming i have a thread.event and this can check before/after the task is done. But is there a way to tell the already running thread to stop or exit it's execution.
There's no way to stop your running thread if DO_MY_30_SECONDS_WORK(self) is blocking. Well arguably you could set it as daemon thread and it'll be abruptly killed when your main program execution finishes, this would cause problems if the thread is actually holding resources (e.g. writing to a file) and is generally not a good idea to finish a thread.
What you could do is re-design DO_MY_30_SECONDS_WORK(self) and make it non-blocking, which means cutting the work into small pieces and make it check for the stop sign in a reasonable interval, so that your thread will be responsive enough to finish itself when you tell it to do so.

Find a python threads state (whether sleeping or active)

I have a simple requirement, when an event occurs a thread is created and sleeps for x minutes before waking up to carry out its tasks and terminate.
But if another event occurs any thread that is sleeping should be terminated and a new thread should be spawned for the same purpose.
In python I believe the best way to make a thread sleep is,
import time
time.sleep(x*60)
Is there a way to learn the state of a thread (currently sleeping/idle or alive)?
There is really no way to do this well as a thread is either alive(running) or not. Technically even if its sleeping it still running/alive its just not doing anything.
In general using sleeps in a thread is not really desirable as it can be a pain to adjust the time it sleeps and/or wake it when you need it to do something.
One thing I have used in the past for this is Condition in the threading module. This allows you to put a thread to "sleep" by calling .wait(). You can then to an .acquire(false) to see if its blocked, and then .acquire() .notify() .release() to wake it up again if you need to.
Its a simple way to keep a thread around and from spinning or using come crazy sleep paradigm.
Another good option is just to have the thread consume in a while True from a blocking queue (Queue module in python) which will technically manage all that for you.
If you are using something like time.sleep you could set a variable to False and changed to True just after the thread "awake", for instance.
class MyThread(Thread):
def __init__(self):
self.awake = False
def run(self):
time.sleep(x*60)
self.awake = True
def is_sleeping(self):
return not self.awake() and self.isAlive() # You need to know also if you already started the thread
then you could:
if (some_thread.is_sleeping()):
# more code here.
Note: As pointed out by Luke Wahlmeier, since you do thread.start() the thread is running. If hits a line as time.sleep(10) it still running, but now is counting to 10 secs. What this code does is check if the thread execution has reached some execution point (the line after the sleep in this case).

Resource usage of "time.sleep" in loop vs. "threading.Timer"

First method:
import threading
import time
def keepalive():
while True:
print 'Alive.'
time.sleep(200)
threading.Thread(target=keepalive).start()
Second method:
import threading
def keepalive():
print 'Alive.'
threading.Timer(200, keepalive).start()
threading.Timer(200, keepalive).start()
Which method takes up more RAM? And in the second method, does the thread end after being activated? or does it remain in the memory and start a new thread? (multiple threads)
Timer creates a new thread object for each started timer, so it certainly needs more resources when creating and garbage collecting these objects.
As each thread exits immediately after it spawned another active_count stays constant, but there are constantly new Threads created and destroyed, which causes overhead. I'd say the first method is definitely better.
Altough you won't realy see much difference, only if the interval is very small.
Here's an example of how to test this yourself:
And in the second method, does the thread end after being activated? or does it remain in the memory and start a new thread? (multiple threads)
import threading
def keepalive():
print 'Alive.'
threading.Timer(200, keepalive).start()
print threading.active_count()
threading.Timer(200, keepalive).start()
I also changed the 200 to .2 so it wouldn't take as long.
The thread count was 3 forever.
Then I did this:
top -pid 24767
The #TH column never changed.
So, there's your answer: We don't have enough info to know whether Python maintains a single timer thread for all of the timers, or ends and cleans up the thread as soon as the timer runs, but we can be sure the threads doesn't stick around and pile up. (If you do want to know which of the former is happening, you can, e.g., print the thread ids.)
An alternative way to find out is to look at the source. As the documentation says, "Timer is a subclass of Thread and as such also functions as an example of creating custom threads". The fact that it's a subclass of Thread already tells you that each Timer is a Thread. And the fact that it "functions as an example" implies that it ought to be easy to read. If you click the link form the documentation to the source, you can see how trivial it is. Most of the work is done by Event, but that's in the same source file, and it's almost as simple. Effectively, it just creates a condition variable, waits on it (so it blocks until it times out, or you notify the condition by calling cancel), then quits.
The reason I'm answering one sub-question and explaining how I did it, rather than answering each sub-question, is because I think it would be more useful for you to walk through the same steps.
On further reflection, this probably isn't a question to be decided by optimization in the first place:
If you have a simple, synchronous program that needs to do nothing for 200 seconds, make a blocking call to sleep. Or, even simpler, just do the job and quit, and pick an external tool to schedule your script to run every 200s.
On the other hand, if your program is inherently asynchronous—especially if you've already got thread, signal handlers, and/or an event loop—there's just no way you're going to get sleep to work. If Timer is too inefficient, go to PyPI or ActiveState and find a better timer that lets you schedule repeatable timers (or even multiple timers) with a single instance and thread. (Or, if you're using signals, use signal.alarm or setitimer, and if you're using an event loop, build the timer into your main loop.)
I can't think of any use case where sleep and Timer would both be serious contenders.

Categories

Resources