I'm working on a simple shell program with Python, and I need to repeat a task (a simple os.system call ) every second.
Is it possible to make that, without interrupting the program flow ?
Like a multithreaded thing?
Thanks in advance.
without threading
import time
while True:
time.sleep(1)
do_stuff()
with threading
import threading
import time
def my_func():
while True:
time.sleep(1)
do_stuff()
t1 = threading.Thread(target=my_func)
t1.start()
Related
Im pretty independent when using oython since i wouldnt consider myself a beginner etc, but Iv been coding up a program that I want to sell. The problem is that I want the program to have a timer on it and when it runs out the program will no longer work. Giving the user a specified amount of time they have to use the program.
You will want to run your program from another program using multithreading or asynchronous stuff. If you are looking for a single thing to send to your program (here, an interruption signal), then you should take a look at the signal built in package (for CPython).
(based on this answer from another post)
If you're calling external script using subprocess.Popen, you can just .kill() it after some time.
from subprocess import Popen
from time import sleep
with Popen(["python3", script_path]) as proc:
sleep(1.0)
proc.kill()
Reading documentation helps sometimes.
One way this can be done by interrupting the main thread
from time import sleep
from threading import Thread
from _thread import interrupt_main
import sys
TIME_TO_WAIT = 10
def kill_main(time):
sleep(time)
interrupt_main()
thread = Thread(target=kill_main, args=(TIME_TO_WAIT,))
thread.start()
try:
while True:
print('Main code is running')
sleep(0.5)
except KeyboardInterrupt: print('Time is up!')
sys.exit()
Here's my code:
import _thread
import time
def print_time(name, delay):
count=1
while count<=5:
time.delay(delay)
print ("Thread %s Time is %s"%(count, time.ctime(time.time())))
count = count+1
_thread.start_new_thread(print_time,("T-1",2))
_thread.start_new_thread(print_time,("T-2",4))
The output should be various lines telling the current time. But after running the program I got no output and no error. Why is this happening? I use Python 3.6.
Probably the first question is why you're using _thread. I am guessing your issue is that your main thread finishes before print_time manages to produce any output, and on this particular system, that exits the whole program.
From the section Caveats in the _thread documentation:
When the main thread exits, it is system defined whether the other threads survive. On most systems, they are killed without executing try … finally clauses or executing object destructors.
When using threading instead, you get to choose whether to await threads with the daemon argument.
The above answers are always the better options but if you still insist on doing with _thread module just delay the main thread by adding time.sleep(1) at the end of the code
Use threading:
import threading
import time
def print_time(name, delay):
count=1
while count<=5:
time.sleep(delay)
print ("Thread %s Time is %s"%(count, time.ctime(time.time())))
count = count+1
t1 = threading.Thread(target=print_time, args=("T-1",2))
t2 = threading.Thread(target=print_time, args=("T-2",4))
t1.start()
t2.start()
The threading module provides an easier to use and higher-level threading API built on top of this [_thread] module.
This question already has answers here:
Best way to implement a non-blocking wait?
(5 answers)
Closed 1 year ago.
I need to run my Python program forever in an infinite loop..
Currently I am running it like this -
#!/usr/bin/python
import time
# some python code that I want
# to keep on running
# Is this the right way to run the python program forever?
# And do I even need this time.sleep call?
while True:
time.sleep(5)
Is there any better way of doing it? Or do I even need time.sleep call?
Any thoughts?
Yes, you can use a while True: loop that never breaks to run Python code continually.
However, you will need to put the code you want to run continually inside the loop:
#!/usr/bin/python
while True:
# some python code that I want
# to keep on running
Also, time.sleep is used to suspend the operation of a script for a period of time. So, since you want yours to run continually, I don't see why you would use it.
How about this one?
import signal
signal.pause()
This will let your program sleep until it receives a signal from some other process (or itself, in another thread), letting it know it is time to do something.
I know this is too old thread but why no one mentioned this
#!/usr/bin/python3
import asyncio
loop = asyncio.get_event_loop()
try:
loop.run_forever()
finally:
loop.close()
sleep is a good way to avoid overload on the cpu
not sure if it's really clever, but I usually use
while(not sleep(5)):
#code to execute
sleep method always returns None.
Here is the complete syntax,
#!/usr/bin/python3
import time
def your_function():
print("Hello, World")
while True:
your_function()
time.sleep(10) #make function to sleep for 10 seconds
for OS's that support select:
import select
# your code
select.select([], [], [])
I have a small script interruptableloop.py that runs the code at an interval (default 1sec), it pumps out a message to the screen while it's running, and traps an interrupt signal that you can send with CTL-C:
#!/usr/bin/python3
from interruptableLoop import InterruptableLoop
loop=InterruptableLoop(intervalSecs=1) # redundant argument
while loop.ShouldContinue():
# some python code that I want
# to keep on running
pass
When you run the script and then interrupt it you see this output, (the periods pump out on every pass of the loop):
[py36]$ ./interruptexample.py
CTL-C to stop (or $kill -s SIGINT pid)
......^C
Exiting at 2018-07-28 14:58:40.359331
interruptableLoop.py:
"""
Use to create a permanent loop that can be stopped ...
... from same terminal where process was started and is running in foreground:
CTL-C
... from same user account but through a different terminal
$ kill -2 <pid>
or $ kill -s SIGINT <pid>
"""
import signal
import time
from datetime import datetime as dtt
__all__=["InterruptableLoop",]
class InterruptableLoop:
def __init__(self,intervalSecs=1,printStatus=True):
self.intervalSecs=intervalSecs
self.shouldContinue=True
self.printStatus=printStatus
self.interrupted=False
if self.printStatus:
print ("CTL-C to stop\t(or $kill -s SIGINT pid)")
signal.signal(signal.SIGINT, self._StopRunning)
signal.signal(signal.SIGQUIT, self._Abort)
signal.signal(signal.SIGTERM, self._Abort)
def _StopRunning(self, signal, frame):
self.shouldContinue = False
def _Abort(self, signal, frame):
raise
def ShouldContinue(self):
time.sleep(self.intervalSecs)
if self.shouldContinue and self.printStatus:
print( ".",end="",flush=True)
elif not self.shouldContinue and self.printStatus:
print ("Exiting at ",dtt.now())
return self.shouldContinue
If you mean run as service then you can use any rest framework
from flask import Flask
class A:
def one(port):
app = Flask(__name__)
app.run(port = port)
call it:
one(port=1001)
it will always keep listening on 1001
* Running on http://127.0.0.1:1001/ (Press CTRL+C to quit)
I am somewhat new to python. I have been trying to find the answer to this coding question for some time. I have a function set up to run on a threading timer. This allows it to execute every second while my other code is running. I would like this function to simply execute continuously, that is every time it is done executing it starts over, rather than on a timer. The reason for this is that due to a changing delay in a stepper motor the function takes different amounts of time run.
Is this what you're looking for?
from threading import Thread
def f():
print('hello')
while True:
t = Thread(target=f)
t.start()
t.join()
Or maybe this, which shows the concurrent paths of execution (for production, remove sleep() calls, of course):
from threading import Thread
from time import sleep
def g():
print('hello')
sleep(1)
def f():
while True: g()
Thread(target=f).start()
sleep(1)
print('other code here')
Alright I've been using the time module for time.sleep(x) function for awhile... but I need something that won't pause the shell and so the user can continue using the program while it's counting.
To be more "specific" let's suppose I had a program that needed to wait 5 seconds before executing a function. In this time using the time.sleep() function the user can't type anything into the shell because it's sleeping. However, I need Python to "count the 5 seconds" in the background while the user is able to use the shell. Is this possible?
threading ? You should handle piece of your work in one worker and another separate worker where you would count or sleep with time.sleep
Here is an example that might help you understand and use threading with time.sleep
import threading
import time
def sleeper():
print 'Starting to sleep'
time.sleep(10)
print 'Just waking up..'
print 'snooze'
print 'oh no. I have to get up.'
def worker():
print 'Starting to work'
time.sleep(1) # this also a work. :)
print 'Done with Work'
t = threading.Thread(name='sleeper', target=sleeper)
w = threading.Thread(name='worker', target=worker)
w.start()
t.start()