I need to schedule a python script which can exit and kill it self at a given time. For scheduling, I am using python schedule and below is the code:
import schedule
from threading import Thread
import time
import sys
def exit_data():
print("Exiting")
sys.exit()
def exit_data_thread():
schedule.every().day.at('13:20').do(exit_data)
while True:
schedule.run_pending()
time.sleep(1)
def main():
Thread(target=exit_data_thread).start()
while True:
time.sleep(1)
main()
Function exit_data() runs at given time and it prints Exiting but do not exit. It only prints Exiting and then it keeps running. I have also used quit instead of sys.exit(). Please help. Thanks
Try to send signal to yourself :p
import schedule
from threading import Thread
import time
import sys
import os
import signal
def exit_data():
print("Exiting")
# sys.exit()
os.kill(os.getpid(), signal.SIGTERM)
def exit_data_thread():
schedule.every(3).seconds.do(exit_data)
while True:
schedule.run_pending()
time.sleep(1)
def main():
Thread(target=exit_data_thread).start()
while True:
time.sleep(1)
main()
To close the entire program within a thread, you can use os._exit(). Calling sys.exit() will only exit the thread, not the entire program.
Related
I have two python function which I want to run in parallel. I don't want sub_task function to wait for main_task function.
from threading import Thread
from multiprocessing import Process
from time import sleep,time
def main_task():
while True:
sleep(2)
print('main task running')
def sub_task():
while True:
sleep(5)
print('sub task running')
When I used thread this way, I can see output
q=Thread(target = main_task).start()
s=Thread(target = sub_task).start()
But when I used Process this way, I cannot see ouput
q=Process(target = main_task).start()
s=Process(target = sub_task).start()
So what is wrong with the implementation.
(Python 3.8.3)
I am using two python threads right now, one that has a while True loop
import threading
def threadOne():
while True:
do(thing)
print('loop ended!')
t1=threading.Thread(threadOne)
t1.start()
And another that checks for a ctrl+r input. When recieved, I need the second thread to tell the first thread to break from the while loop. Is there a way to do this?
Note that I cannot change the loop to 'while Break == False' as do(thing) waits for user input, but i need this to be interrupted.
The recommended way is to use threading.event (You can combine this with event.wait if you want to sleep in that thread too however as you are waiting for a user event, probably dont need that).
import threading
e = threading.Event()
def thread_one():
while True:
if e.is_set():
break
print("do something")
print('loop ended!')
t1=threading.Thread(target=thread_one)
t1.start()
# and in other thread:
import time
time.sleep(0.0001) # just to show thread_one keeps printing
# do something for little bit and then it break
e.set()
EDIT: To interrupt the thread while it's waiting for user input you can send SIGINT to that thread and and it will raise KeyboardInterrupt which you can then handle. Unfortunate limitation of python, including python3, is that signals to all threads are handled in the main thread so you need to wait for the user input in the main thread:
import threading
import sys
import os
import signal
import time
def thread_one():
time.sleep(10)
os.kill(os.getpid(), signal.SIGINT)
t1=threading.Thread(target=thread_one)
t1.start()
while True:
try:
print("waiting: ")
sys.stdin.readline()
except KeyboardInterrupt:
break
print("loop ended")
I am trying to make a console for my python applications, but i ran into a problem:
when printing something using the print() function, the text in the input field is also included. This is purely visual, because the program still works.
I tried searching online, but I do not even now what to search for and had no luck.
This is my code. It prints "foo" until the user types "exit":
import multiprocessing as mp
import os
import time
def f(q):
while True:
print(q)
time.sleep(1)
if __name__=="__main__":
p=mp.Process(target=f, args=("foo",))
p.start()
while True:
comm=str(input())
if comm=="exit":
p.terminate()
break
When the program is running, the user can still type, but when the program prints something, it also takes whatever is in the input field at the time:
foo
foo
foo
foo
efoo
xfoo
itfoo
When pressing "enter", the program still registers the input correctly and exits the program.
Here is a modification of your code that only prints foo after you have finished your input typing (i.e., until you hit Enter):
import multiprocessing as mp
from multiprocessing import Queue
def f(q, queue):
while True:
queue.get()
print(q)
if __name__=="__main__":
queue = Queue()
p=mp.Process(target=f, args=("foo", queue))
p.start()
while True:
comm=str(input())
queue.put(None)
if comm=="exit":
p.terminate()
break
If terminating the process is all you want your user to be able to do, then you can instruct them to enter Ctrl+C if they wish to stop the operation and then catch the KeyboardInterrupt exception that comes along with it.
import multiprocessing as mp
import os
import time
def f(q):
while True:
print(q)
time.sleep(1)
if __name__=="__main__":
p=mp.Process(target=f, args=("foo",))
print("Process starting. Use Ctrl+c anytime to stop it!")
p.start()
try:
while True:
input() # Trash command
except KeyboardInterrupt:
print("Terminating process...")
p.terminate()
print("Process terminated...")
If you want to do more complicated commands then a GUI would be your best approach (as mentioned by John)
I have a script and it doesn't work proper, so in bash I let script in while loop and I wanna my script can close itself after a while, I tried to use threading.timer but my code wont run quit() or exit() command, could anyone please help me?
#!/usr/bin/env python3
import threading
from time import sleep
def qu():
print("bye")
exit()
t=threading.Timer(5.0,qu)
t.start()
while(True):
sleep(1)
print("hi")
You could use the os._exit function instead of exit()
Getting the code as follows:
#!/usr/bin/env python3
import threading
import os
from time import sleep
def qu():
print("bye")
os._exit(0)
t=threading.Timer(5.0,qu)
t.start()
while(True):
sleep(1)
print("hi")
Anyways I would suggest you to checkout this question as it is similar to yours.
I have following code which compares user input
import thread,sys
if(username.get_text() == 'xyz' and password.get_text()== '123' ):
thread.start_new_thread(run,())
def run():
print "running client"
start = datetime.now().second
while True:
try:
host ='localhost'
port = 5010
time = abs(datetime.now().second-start)
time = str(time)
print time
client = socket.socket()
client.connect((host,port))
client.send(time)
except socket.error:
pass
If I just call the function run() it works but when I try to create a thread to run this function, for some reason the thread is not created and run() function is not executed I am unable to find any error..
Thanks in advance...
you really should use the threading module instead of thread.
what else are you doing? if you create a thread like this, then the interpreter will exit no matter if the thread is still running or not
for example:
import thread
import time
def run():
time.sleep(2)
print('ok')
thread.start_new_thread(run, ())
--> this produces:
Unhandled exception in thread started by
sys.excepthook is missing
lost sys.stderr
where as:
import threading
import time
def run():
time.sleep(2)
print('ok')
t=threading.Thread(target=run)
t.daemon = True # set thread to daemon ('ok' won't be printed in this case)
t.start()
works as expected. if you don't want to keep the interpreter waiting for the thread, just set daemon=True* on the generated Thread.
*edit: added that in example
thread is a low level library, you should use threading.
from threading import Thread
t = Thread(target=run, args=())
t.start()