Restart a python script from backround_thread - python

I've been spending some time in searching for the correct code but I got no luck.
I have below python script with background thread and a main prog.. I want to restart the script once the background thread encounters a condition. Hope you can help me with this. TIA
With this script, both background_stuff and "main" are running at the same time.
def background_stuff():
while True:
if condition == 'True':
### restart the script
t = Thread(target=background_stuff)
t.start()
### main
if __name__ == '__main__':
while True:
#do something

Can you restructure your script like so?
def main():
t = Thread(target=background_stuff)
t.start()
while True:
#do something
def background_stuff():
while True:
if condition == 'True':
### restart the script
#t = Thread(target=background_stuff)
#t.start()
### main
if __name__ == '__main__':
main()
Calling main now should create a new thread that will run the background stuff and the script basically restarts. The only issue is that state is not reset. If you need to reset state then you could actually run your script from scratch from within your script using:
os.system("yourScript.py -yourargs")
I don't think this is best practice though...
Regardless of which solution you end up using, you still need to terminate the old main loop. This could either be done by setting some flag when you "restart your script" and then have the main loop periodically check for that flag and do a controlled shut down once the flag is set, or you can run the main loop in another thread which you can access globally or from the other thread and then terminate it. Just remember that forcibly shutting down a thread is often not adviced.

Related

Have a thread constantly run in background python

I have a function to check for sniffing tools I want to constantly run in the background of my python script:
def check():
unwanted_programmes = [] # to be added to
for p in psutil.process_iter(attrs=['pid', 'name']):
for item in unwanted_programmes:
if item in str(p.info['name']).lower():
webhook_hackers(str(p.info['name'])) # send the programme to a webhook which is in another function
sys.exit()
time.sleep(1)
I want this to run right from the start and then the rest of the script
I have written code like so:
if __name__ == "__main__":
check = threading.Thread(target=get_hackers())
check.start()
check.join()
threading.Thread(target=startup).start()
# startup function just does some prints and inputs before running other functions
However, this code only runs check once and then startup but I want check to run and then keep running in the background. Meanwhile, startup to run just once, how would I do this?
Your check function does what you want it to, but it only does it once, and that's the behavior that you're seeing; the thread finishes running the function and then cleanly exits. If you place everything in the function inside of a while(True): block at the top of the function then the function will loop infinitely and the thread will never exit, which sounds like it's what you want.

How to run a function in the background while running other ones in the front?

I'm sort of new to python, and I'm trying to build a voice-controlled home automation system. Everything's going out really well, except for one thing.
I need the system to stop whatever it's doing when I say 'stop.' for example, when it's playing music, or when it's telling me the news, if I say "stop", it stop everything and go back to standby mode.
How can I make it so that there's a python process in the background always listening for a "stop" while doing other stuff in the front?
this is my code for the particular part:
def stop():
#code_that_listens_for_"stop"
def main():
#code_that_listens_and_executes_commands
# runs at the start of the program
if __name__ == '__main__':
Thread(target = main).start()
Thread(target = stop).start()
is my code correct?
Thanks! This is my first question at stackexchange, any help would be greatly appreciated ^^
Instead Of Thread use Process you will get more advantages like no gil, fast, efficient
from multiprocessing import Process
def stop():
#code_that_listens_for_"stop"
def main():
#code_that_listens_and_executes_commands
# runs at the start of the program
if __name__ == '__main__':
Process(target=stop).start()
Process(target=main).start()

Running Python multi-threaded process & interrupt a child thread with a signal

I am trying to write a Python multi-threaded script that does the following two things in different threads:
Parent: Start Child Thread, Do some simple task, Stop Child Thread
Child: Do some long running task.
Below is a simple way to do it. And it works for me:
from multiprocessing import Process
import time
def child_func():
while not stop_thread:
time.sleep(1)
if __name__ == '__main__':
child_thread = Process(target=child_func)
stop_thread = False
child_thread.start()
time.sleep(3)
stop_thread = True
child_thread.join()
But a complication arises because in actuality, instead of the while-loop in child_func(), I need to run a single long-running process that doesn't stop unless it is killed by Ctrl-C. So I cannot periodically check the value of stop_thread in there. So how can I tell my child process to end when I want it to?
I believe the answer has to do with using signals. But I haven't seen a good example of how to use them in this exact situation. Can someone please help by modifying my code above to use signals to communicate between the Child and the Parent thread. And making the child-thread terminate iff the user hits Ctrl-C.
There is no need to use the signal module here unless you want to do cleanup on your child process. It is possible to stop any child processes using the terminate method (which has the same effect as SIGTERM)
from multiprocessing import Process
import time
def child_func():
time.sleep(1000)
if __name__ == '__main__':
event = Event()
child_thread = Process(target=child_func)
child_thread.start()
time.sleep(3)
child_thread.terminate()
child_thread.join()
The docs are here: https://docs.python.org/2/library/multiprocessing.html#multiprocessing.Process.terminate

Python time.sleep lock process

I want to create multi process app. Here is sample:
import threading
import time
from logs import LOG
def start_first():
LOG.log("First thread has started")
time.sleep(1000)
def start_second():
LOG.log("second thread has started")
if __name__ == '__main__':
### call birhtday daemon
first_thread = threading.Thread(target=start_first())
### call billing daemon
second_thread = threading.Thread(target=start_second())
### starting all daemons
first_thread.start()
second_thread.start()
In this code second thread does not work. I guess, after calling sleep function inside first_thread main process is slept. I found this post. But here sleep was used with class. I got that(Process finished with exit code 0
) as a result when I run answer. Could anybody explain me where I made a mistake ?
I am using python 3.* on windows
When creating your thread you are actually invoking the functions when trying to set the target for the Thread instead of passing a function to it. This means when you try to create the first_thread you are actually calling start_first which includes the very long sleep. I imagine you then get frustrated that you don't see the output from the second thread and kill it, right?
Remove the parens from your target= statements and you will get what you want
first_thread = threading.Thread(target=start_first)
second_thread = threading.Thread(target=start_second)
first_thread.start()
second_thread.start()
will do what you are trying

Python: Timer, how to stop thread when program ends?

I have a function I'm calling every 5 seconds like such:
def check_buzz(super_buzz_words):
print 'Checking buzz'
t = Timer(5.0, check_buzz, args=(super_buzz_words,))
t.dameon = True
t.start()
buzz_word = get_buzz_word()
if buzz_word is not 'fail':
super_buzz_words.put(buzz_word)
main()
check_buzz()
I'm exiting the script by either catching a KeyboardInterrupt or by catching a System exit and calling this:
sys.exit('\nShutting Down\n')
I'm also restarting the program every so often by calling:
execv(sys.executable, [sys.executable] + sys.argv)
My question is, how do I get that timer thread to shut off? If I keyboard interrupt, the timer keeps going.
I think you just spelled daemon wrong, it should have been:
t.daemon = True
Then sys.exit() should work
Expanding on the answer from notorious.no, and the comment asking:
How can I call t.cancel() if I have no access to t oustide the
function?
Give the Timer thread a distinct name when you first create it:
import threading
def check_buzz(super_buzz_words):
print 'Checking buzz'
t = Timer(5.0, check_buzz, args=(super_buzz_words,))
t.daemon = True
t.name = "check_buzz_daemon"
t.start()
Although the local variable t soon goes out of scope, the Timer thread that t pointed to still exists and still retains the name assigned to it.
Your atexit-registered method can then identify this thread by its name and cancel it:
from atexit import register
def all_done():
for thr in threading._enumerate():
if thr.name == "check_buzz_daemon":
if thr.is_alive():
thr.cancel()
thr.join()
register(all_done)
Calling join() after calling cancel()is based on a StackOverflow answer by Cédric Julien.
HOWEVER, your thread is set to be a Daemon. According to this StackOverflow post, daemon threads do not need to be explicitly terminated.
from atexit import register
def all_done():
if t.is_alive():
# do something that will close your thread gracefully
register(all_done)
Basically when your code is about to exit, it will fire one last function and this is where you will check if your thread is still running. If it is, do something that will either cancel the transaction or otherwise exit gracefully. In general, it's best to let threads finish by themselves, but if it's not doing anything important (please note the emphasis) than you can just do t.cancel(). Design your code so that threads will finish on their own if possible.
Another way would be to use the Queue() module to send and recieve info from a thread using the .put() outside the thread and the .get() inside the thread.
What you can also do is create a txt file and make program write to it when you exit And put an if statement in the thread function to check it after each iteration (this is not a really good solution but it also works)
I would have put a code exemple but i am writing from mobile sorry

Categories

Resources