How do I pause this thread after x minutes - python

How to pause this thread from running every 300 seconds for 500 seconds? I need to suspend it from running all the functions every x minutes to prevent API breaches. Timer objects seem to only start the code, whereas the objective is to pause, wait, resume.
from TwitterFollowBot import TwitterBot
from threading import Thread
import random
my_bot = TwitterBot()
my_bot.sync_follows()
def a():
my_bot.auto_fav("#asco", count=1000)
def b():
my_bot.auto_fav("ATSO", count=1000)
def c():
my_bot.auto_fav("BCY3", count=1000)
lof = [a, b, c]
random.shuffle(lof)
for z in lof:
Thread(target=z).start()
Credit to #Farhan.K for assisting with the code.

Maybe something like this for your threads?
import time
def sleep_thread(sleepWait, sleepTime):
timeStart = time.time()
timeElapsed = 0
while timeElapsed <= sleepWait:
timeElapsed = time.time() - timeStart
print 'time elapsed = ' + str(timeElapsed)
time.sleep(1)
print 'going to sleep. zzz....'
# Sleep for x
time.sleep(sleepTime)
print 'im awake!'
sleep_thread(5, 3)

Related

How can I increment a variable inside a function without using global variable please?

I need a way to print a timer every second and execute an action every 10 seconds.
The output of the program should be like below.
Timer is 1
Timer is 2
Timer is 3
Timer is 4
Timer is 5
Timer is 6
Timer is 7
Timer is 8
Timer is 9
Timer is 10
Action is executed
Timer is 1
Timer is 2
Timer is 3
Timer is 4
Timer is 5
Timer is 6
Timer is 7
Timer is 8
Timer is 9
Timer is 10
Action is executed
Timer is 1
Timer is 2
Timer is 3
.
.
.
The program should use threading. It should not be an infinite while loop.
I could have done it with below code but it uses a global variable. How can I do it without using a global variable and with a small amount of code like below.
import threading
import time
global MytTimer
MytTimer=0
def foo():
global MytTimer
MytTimer=MytTimer+1
print("Timer is " + str(MytTimer))
threading.Timer(1, foo).start()
if MytTimer >= 10:
MytTimer=0
print("Action is executed")
foo()
I did it by creating a class.
import threading
import time
class count():
def __init__(self, MytTimer):
self.MytTimer = MytTimer
self._run()
def _run(self):
threading.Timer(1, self._run).start()
self.MytTimer += 1
print("Timer is " + str(self.MytTimer))
if self.MytTimer >= 10:
self.MytTimer=0
print("Action is executed")
a=count(MytTimer = 0)
You could create a ticker thread that delivers values 1-10 to a queue, and then a consumer that executes an action whenever the value read from the queue is 10:
import threading
import time
import queue
def foo():
q = queue.Queue()
def ticker():
while True:
for i in range(1,11):
print(f'Timer is {i}')
q.put(i)
time.sleep(1)
t_ticker = threading.Thread(target=ticker)
t_ticker.start()
while True:
i = q.get()
if i == 10:
print("Action is executed")
foo()

Problem with variable name 'start_time' is not defined

Import threading module
import threading
Import time module to implement sleep functionality
import time
Import datetime to get start time, end time and elapsed time
from datetime import datetime
#Function to loop 100000 times
def loop_fun(name):
for i in range(0, 10):
time.sleep(0.0001)
print(name)
print("Loop executed!")
#Function to execute loop_fun without multithreading
num =0
def without_thread(num):
starting_time = datetime.now()
for i in range(0, num):
loop_fun("Called from without_thread")
ending_time = datetime.now()
elapsed_time = (ending_time - starting_time).total_seconds()
print("\n\nTime Elapsed without_thread: "+ str(elapsed_time)+"\n\n\n\n\n")
#Function to execute loop_fun with multithreading"
def with_thread(num):
start_time = datetime.now()
threads_lst = []
# Creating threads to call loop_fun
for i in range(0, num):
threads_lst.append(threading.Thread(target=loop_fun, args=("Called from with_thread",)))
# Running threads
for threads_ in threads_lst:
threads_.start()
# Waiting for completion of all threads
for threads_ in threads_lst:
threads_.join()
end_time = datetime.now()
elapsed_time = (end_time - start_time).total_seconds()
print("\n\nTime Elapsed with_thread: "+ str(elapsed_time)+"\n\n\n\n\n")
if __name__ == "__main__":
without_thread(10)
with_thread(10)
Your indentation is messed up. Copy/paste issue or does your code look like that ?
Missing Indentation in Python makes it hard to guess what you are trying to achieve.
Nevertheless I tried and came up with this code working w/o errors. Does it do what you want ? I frankly don't know.
I added these lines, which got messed up by the forum I think
from datetime import datetime
import time
import threading
I "fixed" indentation
#Function to loop 100000 times
def loop_fun(name):
for i in range(0, 10):
time.sleep(0.0001)
print(name)
print("Loop executed!")
#Function to execute loop_fun without multithreading
num =0
def without_thread(num):
starting_time = datetime.now()
for i in range(0, num):
loop_fun("Called from without_thread")
ending_time = datetime.now()
elapsed_time = (ending_time - starting_time).total_seconds()
print("\n\nTime Elapsed without_thread: "+ str(elapsed_time)+"\n\n\n\n\n")
#Function to execute loop_fun with multithreading"
def with_thread(num):
start_time = datetime.now()
threads_lst = []
# Creating threads to call loop_fun
for i in range(0, num):
threads_lst.append(threading.Thread(target=loop_fun, args=("Called from with_thread",)))
# Running threads
for threads_ in threads_lst:
threads_.start()
# Waiting for completion of all threads
for threads_ in threads_lst:
threads_.join()
end_time = datetime.now()
elapsed_time = (end_time - start_time).total_seconds()
print("\n\nTime Elapsed with_thread: "+ str(elapsed_time)+"\n\n\n\n\n")
if __name__ == "__main__":
without_thread(10)
with_thread(10)
It's printing stuff like that
Loop executed!
Called from without_thread
Loop executed!
Called from without_thread
Loop executed!
Time Elapsed without_thread: 6.378763

Python does something every 5 minutes

i need to check data on an API. The API is refreshed with new data every 5 minutes (10:00, 10:05, 10:10 etc...)
I don't want to use time.sleep(300) because i want my script to do something at 10:05:03, then 10:05:03 etc. and not 5 min avec the script started (maybe it started at 10h12
How can i build this?
Thanks y'all.
UPDATE:
Just wanted to remove the possibility of recursion error, so I have rewritten the code:
from threading import Thread
from time import sleep
import datetime
def check_api():
# ... your code here ...
pass
def schedule_api():
while datetime.datetime.now().minute % 5 != 0:
sleep(1)
check_api()
while True:
sleep(300)
check_api()
thread = Thread(target=schedule_api)
thread.start()
Also if you want your thread to quit when the main program exits you could set daemon as True on the thread like:
thread.daemon = True
But this does not enforce a clean termination of this thread so you could also try this approach below:
# ...
RUNNING = True
# ...
thread = Thread(target=schedule_api)
thread.start()
#...
def main():
# ... all main code ...
pass
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
RUNNING = False
You can use the following code:
import threading
def check_api():
pass
timer_thread = threading.Timer(300, check_api)
timer_thread.start()
# call timer_thread.cancel() when you need it to stop
This will call your check_api function every 5 minutes and will not block your main code's execution.
as mentioned by #scotyy3785 the above code will only run once but I realize what you want and have written the code for it:
from threading import Thread
from time import sleep
import datetime
def check_api():
# ... your code here ...
pass
def caller(callback_func, first=True):
if first:
while not datetime.datetime.now().minute % 5 == 0:
sleep(1)
callback_func()
sleep(300)
caller(callback_func, False)
thread = Thread(target=caller, args=(check_api,))
thread.start()
# you'll have to handle the still running thread on exit
The above code will call check_api at minutes like 00, 05, 10, 15...
Check the time regularly in a loop and do something at certain minute marks:
import time
# returns the next 5 minute mark
# e.g. at minute 2 return 5
def get_next_time():
minute = time.localtime().tm_min
result = 5 - (minute % 5) + minute
if result == 60:
result = 0
return result
next_run = get_next_time()
while True:
now = time.localtime()
# at minute 0, 5, 10... + 3 seconds:
if next_run == now.tm_min and now.tm_sec >= 3:
print("checking api")
next_run = get_next_time()
time.sleep(1)

Python - Execute Function After Amount of Time?

What i'm trying to do is print or execute a certain string after
certain amount of time, in case of this function it is 20 seconds,
the problem is on the second loop, sure it waits 20 seconds on first loop,
but the second loop it no longer wait, it just keeps printing..
why does this happen? and how can i solve it?
from threading import Timer
import time
startlog = time.time()
def tess():
tm = 0
while True:
tm += 1
print(tm)
tess()
time.sleep(1)
You need to reset startlog between calls to tess that "succeed" (have passed 20 s), this code works the way you want (but is ugly because of the global variables).
import time
startlog = time.time()
def tess():
global startlog
if time.time() - 20 > startlog:
print('its been 20 secs')
startlog = time.time()
tm = 0
while True:
tm += 1
print(tm)
tess()
time.sleep(1)
You need to update your startlog variable inside loop in tess() function. You need to replace
start = time.time()
with:
startlog = time.time()
You have to change start = time.time() to startlog = time.time() and define such variable as global or nonlocal:
def tess():
nonlocal startlog
...
startlog = time.time()
Or just wait 20 secs: time.sleep(20)
It sounds like you are trying to run something for 20 seconds in the background, and then execute your function.
If this is the case, you threading / multiprocessing makes more sense.
Using this decorator, your code could be rewritten as
#time_limit(20)
def will_stop_after_20_secs():
print ("doing stuff")
time.sleep(20)
will_stop_after_20_secs()
print ("20 seconds had passed")

Python Threading with Timer

I would like 3 Threads in Python to run for n seconds. I want to start them all at the same time and have them finish at the same time (within milliseconds). How do I do this?
threading.Timer only starts after the previous one has been completed.
import threading
import time
class A(threading.Thread):
def run(self):
print "here", time.time()
time.sleep(10)
print "there", time.time()
if __name__=="__main__":
for i in range(3):
a = A()
a.start()
prints:
here 1279553593.49
here 1279553593.49
here 1279553593.49
there 1279553603.5
there 1279553603.5
there 1279553603.5

Categories

Resources