Increase sleep time after python script executed, while it is running - python

I have a simple python code. It makes something and it sleeps x second and it makes another thing again. I want to extend that sleeping time after I execute the file.
For example
print("A")
time.sleep(x)
print("B")
After I execute the code I want to change and increase the sleeping time before it prints B.
Is it possible? Please help. Thanks.

This solution is using a list with sleep times you can expand by appending further sleeps while your target function is sleeping. The function sleep_all just pops off and executes any sleep available from that list.
import time
from datetime import datetime
from threading import Thread, current_thread
def f():
print(f'{datetime.now()}: A')
sleep_all()
print(f'{datetime.now()}: B')
def sleep_all():
sleeps = current_thread().sleeps
while sleeps:
sleep = sleeps.pop()
print(f'{datetime.now()}: taking a nap for {sleep} s')
time.sleep(sleep)
if __name__ == '__main__':
t = Thread(target=f)
t.sleeps = [5] # attach instance attribute with sleeps-list
t.start()
time.sleep(2)
print(f'{datetime.now()}: adding another sleep')
t.sleeps.append(5)
Example Output:
2018-12-07 22:54:09.733494: A
2018-12-07 22:54:09.733553: taking a nap for 5 s
2018-12-07 22:54:11.735635: adding another sleep
2018-12-07 22:54:14.734963: taking a nap for 5 s
2018-12-07 22:54:19.738833: B
Process finished with exit code 0
Version with subclassing Thread:
import time
from datetime import datetime
from threading import Thread
class Program(Thread):
def __init__(self, sleep=None):
super().__init__()
self._sleeps = [sleep]
def run(self):
print(f'{datetime.now()}: A')
self._sleep_all()
print(f'{datetime.now()}: B')
def add_sleep(self, sleep):
self._sleeps.append(sleep)
def _sleep_all(self):
while self._sleeps:
sleep = self._sleeps.pop()
print(f'{datetime.now()}: taking a nap for {sleep} s')
time.sleep(sleep)
if __name__ == '__main__':
prg = Program(sleep=5)
prg.start()
time.sleep(2)
print(f'{datetime.now()}: adding another sleep')
prg.add_sleep(sleep=5)
prg.join()

#!/usr/bin/env python
import time
try:
with open(".sleeptime") as f:
sleep_time = float(f.read())
except FileNotFoundError:
sleep_time = 5.0
with open(".sleeptime", "w") as f:
next_sleep_time = sleep_time + 5.0
f.write(str(next_sleep_time))
print("A")
time.sleep(sleep_time)
print("B")

Related

How can gevent.sleep() be canceled?

I have a greenlet that does some I/O and figures out how long to sleep until it should be awakened to continue. Say some external event should cause the sleeping greenlet to immediately awaken and continue after the sleep. How can I achieve this?
A solution is killing the greenlet and creating a new one but that seems, well, messy. Another solution I've tried is gevent.wait with a timeout of 0, 0.1, etc. This didn't do anything at all and also seems messy.
import gevent
import gevent.monkey
gevent.monkey.patch_all()
import time
class G(gevent.Greenlet):
def _run(self):
t = self._determine_how_long_to_sleep()
print(f'in run, will sleep for {t}s')
start = time.time()
# how do I make this cancel-able?
gevent.sleep(t)
end = time.time()
# should get here within 1s of canceling the sleep
assert end - start < t + 1
print('success')
def _determine_how_long_to_sleep(self):
"it's not important how we get this number or why"
return 5
g = G()
g.start()
gevent.sleep(1)
# Sure, this works, but not ideal.
g.kill()
g = G()
g.start()
# Does nothing whatsoever:
#gevent.wait(objects=[g], timeout=0.2)
g.join()
The trick is to notice that gevent.Greenlet subclasses greenlet.greenlet which has a throw method that can be caught:
import gevent.monkey
gevent.monkey.patch_all()
import gevent
import time
class InterruptedException(Exception):
pass
class G(gevent.Greenlet):
def _run(self):
t = 5
start = time.time()
try: gevent.sleep(t)
except InterruptedException: pass
end = time.time()
print(f'slept for ~{end-start}s')
assert end - start < t + 1
g = G()
g.start()
gevent.sleep(0)
try:
g.throw(InterruptedException)
except gevent.exceptions.LoopExit:
# There are no other greenlets to switch to so we get this error.
pass
The gevent docs say to avoid using greenlet.throw and prefer higher level abstractions like gevent.event.Event. In my case, having a sleep that can be canceled can be accomplished by this method. Move the logic for knowing you have to cancel the greenlet to calling set on a gevent.event.Event. OK!
import gevent.monkey
gevent.monkey.patch_all()
import gevent
import gevent.event
import time
ev = gevent.event.Event()
class InterruptedException(Exception):
pass
class G(gevent.Greenlet):
def _run(self):
print('will wait for event')
ev.wait()
print('done waiting for event')
g = G()
g.start()
gevent.sleep(2)
ev.set()
print('after event set')

Nothing happened when scheduling a function to start at a certain time

I have a class to start a thread for a while loop. I tried to scheduling the thread class to start within a certain time but it doesn't work:
def test():
if __name__ == "__main__":
main()
schedule.every().day.at("17:25:50").do(test)
The function does not do anything even the time reached "17:25:50"
My full code:
import discord
import random
import time
import asyncio
import schedule
from facebook_scraper import get_posts, _scraper, exceptions
from discord.ext import commands, tasks
import threading
import time
import re
class LEDManager(threading.Thread):
def __init__(self, id_manager):
threading.Thread.__init__(self)
self.id_manager = int(id_manager)
def run(self):
while True:
try:
wanted = "Pecahan setiap negeri (Kumulatif):" # wanted post
for post in get_posts("myhealthkkm", pages=5):
if post.get("post_text") is not None and wanted in post.get("post_text"):
# print("Found", t)
listposts.append(post.get("post_text"))
# append until 3 page finish then go here
time.sleep(1)
print(listposts)
global listView
if listposts != 0:
listView = listposts.copy()
print(listView)
listposts.clear()
except exceptions.TemporarilyBanned:
print("Temporarily banned, sleeping for 10m")
time.sleep(600)
def main():
thread_id = ("0")
led_index = 0
thread_list = list()
for objs in thread_id:
thread = LEDManager(led_index)
thread_list.append(thread)
led_index += 1
for thread in thread_list:
thread.start()
time.sleep(1)
def test():
if __name__ == "__main__":
main()
schedule.every().day.at("17:25:50").do(test)
You forgot to add these lines:
while True:
schedule.run_pending()
time.sleep(1)
You should add them at the end of the file, so the system will keep checking forever, if "the job" needs to be done (if the hour is "17:25:50").
And here is the full documentation to see how to use the schedule module:
https://schedule.readthedocs.io/en/stable/

Execution of two functions parallel

How is it possible to execute two functions with difference of every 5 seconds of time interval till the timer stops using threading in Python.
e.g:
def first_func():
print("First function")
def second_func():
print("Second function")
Result should be like this:
-------------------------------
First Function At starts
Second Function 5 Seconds
First Function 10 Seconds
Second Function 15 Seconds
First Function 20 Seconds
Second Function 25 Seconds
First Function 30 Seconds
And so on.
Try to use multiprocessing
def you_function1(*args, **kwargs):
pass
def you_function2(*args, **kwargs):
pass
from multiprocessing import Process
first_process = Process(target=you_function1)
second_process = Process(target=you_function2)
first_process.start()
second_process.start()
first_process.join()
second_process.join()
https://docs.python.org/2/library/multiprocessing.html
Threading is pretty straightforward for this:
import threading
import time
def first_func():
while True:
print("First function",time.time()-start)
time.sleep(10)
def second_func():
time.sleep(5)
while True:
print("Second function",time.time()-start)
time.sleep(10)
start = time.time()
t1 = threading.Thread(target=first_func)
t1.start()
t2 = threading.Thread(target=second_func)
t2.start()
Output:
First function 0.0
Second function 5.008664846420288
First function 10.002728939056396
Second function 15.010392904281616
First function 20.018056869506836
Second function 25.02572202682495

How I can execute code pararelly or multithread

The following code works for me, the problem is that each thread has to wait until throws to end or at least the perception that I have because when I put the sleep (10) the waiting time is indicated and then continuous.
What I wish is that the haul thread without having to wait for the internal code to run.
It is my code (example):
import threading
from time import sleep
class MyThread(threading.Thread):
def __init__(self, num):
threading.Thread.__init__(self)
self.num = num
def run(self):
print "I'm the thread", self.num
sleep(10)
print "I'm the thread, after 10 seg"
print "I'm the main thread"
for i in range(0, 10):
t = MyThread(i)
t.start()
t.join()
Thanks in advances.
Use 2 for loops: 1 to start the threads and one to wait for them:
# create all threads
ts = [MyThread(i) for i in range(10)]
# start all threads
for t in ts:
t.start()
# wait for all threads
for t in ts:
t.join()

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()

Categories