exit function doesn't work with threading method - python

I need some help with my code
I used to use exit() function in python but today I tried to use threading library
This my code:
import time
import threading
ts = time.time()
ts_after = ts + 5
def printit():
global ts_after
threading.Timer(1.0, printit).start()
ts1 = time.time()
if int(ts1) >= int(ts_after):
print("11")
exit()
else:
pass
printit()
it's work very well and print("11") also work but the exit() after the print doesn't work and keep printing 11

Using the cancel() method on the Timer instance seems to produce your desired behaviour:
import time
import threading
ts = time.time()
ts_after = ts + 5
def printit():
global ts_after
my_thread = threading.Timer(1.0, printit)
my_thread.start()
ts1 = time.time()
if int(ts1) >= int(ts_after):
print("11")
my_thread.cancel()
else:
pass
printit()
The cancel() method simply stops the Timer instance before it has begun. Note that it is probably a good idea to extend this code so that it can also quit Timer objects that have already started.

Related

Is there a solution that allows you to perform a task every specified number of seconds in a thread without putting it to sleep?

like in questien Is there a solution that allows you to perform a task every specified number of seconds in a thread without putting it to sleep in python?
The following code runs thread1 one time after every 30 seconds:
import threading
def thread1:
pass
L1.acquire()
if "__name__" == "__main__":
specific_time = 30
t1 = threading.Thread(target=thread1)
L1 = threading.Lock(blocking=True)
t1.start()
init_time = time.time()
while 1:
if (time.time() - init_time) >= specific_time:
L1.release()
init_time = time.time()
1st way
You can do it useing threading.Timer
from threading import Timer
def hello():
print "hello, world"
t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
2nd way
Just check if the specific time passed. Then run your_function() in a thread
import time
current_milli_time = lambda: int(round(time.time() * 1000))
def your_function():
last_run_millis = current_milli_time()
while 1:
now_millis = current_milli_time()
delta_time = now_millis - last_run_millis
if delta_time > 3000:
last_run_millis = now_millis
print("Do your stuff here")
your_function()

Timer in Python on Windows

If I have a function called a lot of times in a for loop and this function sometimes is running too much time, how can I use a timer for each call of function(to set and reset the timer each time)?
It looks like:
def theFunction(*args):
#some code (timer is on)
#In this point time is out, break and exit function
#Timer is reseted
for i in range(0,100):
theFunction(*args)
Use the time module like so:
import time
time_start = time.time()
#Do function stuff
time_stop = time.time()
#Check your time now
timed_segment = time_stop - time_start
#Repeat if needed
To run this multiple times in a for loop you will need to append times into a list as it runs like so:
import time
def function():
times_list = []
for x in range(10)
time_start = time.time()
#Do function stuff
time_stop = time.time()
#Check your time now
timed_segment = time_stop - time_start
times_list.append(timed_segment)
#Repeat as many times as needed
return times_list
If you want to break after a certain amount of time you can use a while loop instead like so:
import time
def function():
times_list = []
time_start = time.time()
time_end = time.time()
while time_end - time_start < 10: #after 10 seconds the while loop will time out
#Your function does stuff here
time_end = time.time()
#Next, append times to a list if needed
time_list.append(time_start - time_end)
return times_list
To stop the function after a certain time regardless of where it is, we can use threading like so:
import threading
from time import sleep
def do_stuff():
sleep(10)
print("1 + 2")
return
t = threading.Thread(target=do_stuff)
t.start()
t.join(timeout = 5)
In the above example, calling timeout in join will kill the thread after 5 seconds. We can also put this into a decorator if we plan on reusing it many times like so:
import threading
from time import sleep
def timeout(func):
def inner_func(*nums, **kwargs):
t = threading.Thread(target=func, args=(*nums,))
t.start()
t.join(timeout=5)
return inner_func
#timeout
def do_stuff(a,b):
sleep(3)
print(a+b)
return
do_stuff(1,3)
There is another module called timeit which can measure the execution time of small code snippets. I believe you can use that also. I have never used that module but it should work.
Here is the link to the doc page. Give it a look :: https://docs.python.org/2/library/timeit.html
see How to use timeit module as well
For high re-usability and ease of implementations, I would recommend -
Using decorators -
from time import time
def time_it(func):
def wrapper(*args, **kwargs):
a=time()
func(*args, **kwargs)
print(a-time())
return wrapper
#time_it
def foo(s='this works'):
print(s)
foo()
Using profile.run - https://docs.python.org/2/library/profile.html#module-profile

executing specific statement at a given rate in python

I want to write a code which execute a statement specified number of times per second,
Many of you might be familier about the term rate
Here i want rate to be 30 per second
say i want to execute a function 30 times per second for 60 seconds
means rate=30/sec duration=60sec
Can any one tell me is their any api available in python to do the same ?
The sched module is intended for exactly this:
from __future__ import division
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
def schedule_it(frequency, duration, callable, *args):
no_of_events = int( duration / frequency )
priority = 1 # not used, lets you assign execution order to events scheduled for the same time
for i in xrange( no_of_events ):
delay = i * frequency
scheduler.enter( delay, priority, callable, args)
def printer(x):
print x
# execute printer 30 times a second for 60 seconds
schedule_it(1/30, 60, printer, 'hello')
scheduler.run()
For a threaded environment, the use of sched.scheduler can be replaced by threading.Timer:
from __future__ import division
import time
import threading
def schedule_it(frequency, duration, callable, *args, **kwargs):
no_of_events = int( duration / frequency )
for i in xrange( no_of_events ):
delay = i * frequency
threading.Timer(delay, callable, args=args, kwargs=kwargs).start()
def printer(x):
print x
schedule_it(5, 10, printer, 'hello')
Try using threading.Timer:
def hello():
print "hello, world"
t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
You can use time.time() to do what you want:
import time
def your_function():
# do something...
while True:
start = time.time() # gives current time in seconds since Jan 1, 1970 (in Unix)
your_function()
while True:
current_time = time.time()
if current_time - start >= 1.0/30.0:
break
This will make sure that the delay between calls of your_function is very close to 1/30 of a second, even if your_function takes some time to run.
There is another way: using Pythons built-in scheduling module, sched. I never used it, so I can't help you there, but have a look at it.
After some time spending i discovered how to do it well i used multiprocessing in python to achieve it
here's my solution
#!/usr/bin/env python
from multiprocessing import Process
import os
import time
import datetime
def sleeper(name, seconds):
time.sleep(seconds)
print "PNAME:- %s"%name
if __name__ == '__main__':
pros={}
processes=[]
i=0
time2=0
time1=datetime.datetime.now()
for sec in range(5):
flag=0
while flag!=1:
time2=datetime.datetime.now()
if (time2-time1).seconds==1:
time1=time2
flag=1
print "Executing Per second"
for no in range(5):
i+=1
pros[i] = Process(target=sleeper, args=("Thread-%d"%i, 1))
j=i-5
for no in range(5):
j+=1
pros[j].start()
j=i-5
for no in range(5):
j+=1
processes.append(pros[j])
for p in processes:
p.join()

How to end program running after given time in Python

I'd like my Python program to run an algorithm for a given number of seconds and then to print the best result so far and to end.
What is the best way to do so?
I tried the following but it did not work(the program kept running after the printing):
def printBestResult(self):
print(self.bestResult)
sys.exit()
def findBestResult(self,time):
self.t = threading.Timer(time, self.printBestResult)
self.t.start()
while(1):
# find best result
Untested code, but something like this?
import time
threshold = 60
start = time.time()
best_run = threshold
while time.time()-start < threshold:
run_start = time.time()
doSomething()
run_time = time.time() - start
if run_time < best_run:
best_run = run_time
On unix, you can use signals -- This code times out after 1 second and counts how many times it iterates through the while loop in that time:
import signal
import sys
def handle_alarm(args):
print args.best_val
sys.exit()
class Foo(object):
pass
self=Foo() #some mutable object to mess with in the loop
self.best_val=0
signal.signal(signal.SIGALRM,lambda *args: handle_alarm(self))
signal.alarm(1) #timeout after 1 second
while True:
self.best_val+=1 # do something to mutate "self" here.
Or, you could easily have your alarm_handler raise an exception which you then catch outside the while loop, printing your best result.
If you want to do this with threads, a good way is to use an Event. Note that signal.alarm won't work in Windows, so I think threading is your best bet unless in that case.
import threading
import time
import random
class StochasticSearch(object):
def __init__(self):
self.halt_event = threading.Event()
def find_best_result(self, duration):
halt_thread = threading.Timer(duration, self.halt_event.set)
halt_thread.start()
best_result = 0
while not self.halt_event.is_set():
result = self.search()
best_result = result if result > best_result else best_result
time.sleep(0.5)
return best_result
def search(self):
val = random.randrange(0, 10000)
print 'searching for something; found {}'.format(val)
return val
print StochasticSearch().find_best_result(3)
You need an exit condition, or the program will run forever (or until it runs out of memory). Add one yourself.

kill a function after a certain time in windows

I've read a lot of posts about using threads, subprocesses, etc.. A lot of it seems over complicated for what I'm trying to do...
All I want to do is stop executing a function after X amount of time has elapsed.
def big_loop(bob):
x = bob
start = time.time()
while True:
print time.time()-start
This function is an endless loop that never throws any errors or exceptions, period.
I"m not sure the difference between "commands, shells, subprocesses, threads, etc.." and this function, which is why I'm having trouble manipulating subprocesses.
I found this code here, and tried it but as you can see it keeps printing after 10 seconds have elapsed:
import time
import threading
import subprocess as sub
import time
class RunCmd(threading.Thread):
def __init__(self, cmd, timeout):
threading.Thread.__init__(self)
self.cmd = cmd
self.timeout = timeout
def run(self):
self.p = sub.Popen(self.cmd)
self.p.wait()
def Run(self):
self.start()
self.join(self.timeout)
if self.is_alive():
self.p.terminate()
self.join()
def big_loop(bob):
x = bob
start = time.time()
while True:
print time.time()-start
RunCmd(big_loop('jimijojo'), 10).Run() #supposed to quit after 10 seconds, but doesn't
x = raw_input('DONEEEEEEEEEEEE')
What's a simple way this function can be killed. As you can see in my attempt above, it doesn't terminate after 20 seconds and just keeps on going...
***OH also, I've read about using signal, but I"m on windows so I can't use the alarm feature.. (python 2.7)
**assume the "infinitely running function" can't be manipulated or changed to be non-infinite, if I could change the function, well I'd just change it to be non infinite wouldn't I?
Here are some similar questions, which I haven't able to port over their code to work with my simple function:
Perhaps you can?
Python: kill or terminate subprocess when timeout
signal.alarm replacement in Windows [Python]
Ok I tried an answer I received, it works.. but how can I use it if I remove the if __name__ == "__main__": statement? When I remove this statement, the loop never ends as it did before..
import multiprocessing
import Queue
import time
def infinite_loop_function(bob):
var = bob
start = time.time()
while True:
time.sleep(1)
print time.time()-start
print 'this statement will never print'
def wrapper(queue, bob):
result = infinite_loop_function(bob)
queue.put(result)
queue.close()
#if __name__ == "__main__":
queue = multiprocessing.Queue(1) # Maximum size is 1
proc = multiprocessing.Process(target=wrapper, args=(queue, 'var'))
proc.start()
# Wait for TIMEOUT seconds
try:
timeout = 10
result = queue.get(True, timeout)
except Queue.Empty:
# Deal with lack of data somehow
result = None
finally:
proc.terminate()
print 'running other code, now that that infinite loop has been defeated!'
print 'bla bla bla'
x = raw_input('done')
Use the building blocks in the multiprocessing module:
import multiprocessing
import Queue
TIMEOUT = 5
def big_loop(bob):
import time
time.sleep(4)
return bob*2
def wrapper(queue, bob):
result = big_loop(bob)
queue.put(result)
queue.close()
def run_loop_with_timeout():
bob = 21 # Whatever sensible value you need
queue = multiprocessing.Queue(1) # Maximum size is 1
proc = multiprocessing.Process(target=wrapper, args=(queue, bob))
proc.start()
# Wait for TIMEOUT seconds
try:
result = queue.get(True, TIMEOUT)
except Queue.Empty:
# Deal with lack of data somehow
result = None
finally:
proc.terminate()
# Process data here, not in try block above, otherwise your process keeps running
print result
if __name__ == "__main__":
run_loop_with_timeout()
You could also accomplish this with a Pipe/Connection pair, but I'm not familiar with their API. Change the sleep time or TIMEOUT to check the behaviour for either case.
There is no straightforward way to kill a function after a certain amount of time without running the function in a separate process. A better approach would probably be to rewrite the function so that it returns after a specified time:
import time
def big_loop(bob, timeout):
x = bob
start = time.time()
end = start + timeout
while time.time() < end:
print time.time() - start
# Do more stuff here as needed
Can't you just return from the loop?
start = time.time()
endt = start + 30
while True:
now = time.time()
if now > endt:
return
else:
print end - start
import os,signal,time
cpid = os.fork()
if cpid == 0:
while True:
# do stuff
else:
time.sleep(10)
os.kill(cpid, signal.SIGKILL)
You can also check in the loop of a thread for an event, which is more portable and flexible as it allows other reactions than brute killing. However, this approach fails if # do stuff can take time (or even wait forever on some event).

Categories