How do I stop the threads once I found my target? - python

So I wrote a python that will find what the pin the users inputs, everything works fine except one thing, and that's that the script won't exist once the pin is found. Is there a why I can kill all of the other threads once I found the pin?
#!/usr/bin/env python
#
#
#
from threading import Thread
from random import randint
from time import sleep
from sys import exit
from os import system
system('clear');sleep(0.7)
Pin = int(raw_input('Enter a pin: '))
def Up():
global Pin
for pin in xrange(1111,10000):
system('clear')
print pin
if pin == Pin:
system('clear')
print 'U Pin Found: %d'%pin;sleep(0.7)
for i in range(3):
exit()
def Down():
global Pin
pins = xrange(10000)
for pin in reversed(pins):
system('clear')
print pin
if pin == Pin:
system('clear')
print 'D Pin Found: %d'%pin;sleep(0.7)
exit()
def Random():
global Pin
while True:
pins = randint(1111,10000)
print pins
if pins == Pin:
system('clear')
print 'R Pin Found: %d'%pins;sleep(0.7)
exit()
Task1 = Thread(target=Up,args=())
Task2 = Thread(target=Down,args=())
Task3 = Thread(target=Random,args=())
Task1.start()
Task2.start()
Task3.start()

You can't simply terminate them. However you can ask to stop. Please see example:
from threading import Thread
from random import randint
from time import sleep
from sys import exit
from os import system
system('clear');sleep(0.7)
Pin = int(raw_input('Enter a pin: '))
terminateAll = false
def Up():
global Pin
for pin in xrange(1111,10000):
if terminateAll:
exit()
system('clear')
print pin
if pin == Pin:
terminateAll = true
system('clear')
print 'U Pin Found: %d'%pin;sleep(0.7)
for i in range(3):
exit()
def Down():
global Pin
pins = xrange(10000)
for pin in reversed(pins):
if terminateAll:
exit()
system('clear')
print pin
if pin == Pin:
terminateAll = true
system('clear')
print 'D Pin Found: %d'%pin;sleep(0.7)
exit()
def Random():
global Pin
while True:
if terminateAll:
exit()
pins = randint(1111,10000)
print pins
if pins == Pin:
terminateAll = true
system('clear')
print 'R Pin Found: %d'%pins;sleep(0.7)
exit()
Task1 = Thread(target=Up,args=())
Task2 = Thread(target=Down,args=())
Task3 = Thread(target=Random,args=())
Task1.start()
Task2.start()
Task3.start()

All you need to do is make the thread objects daemons by setting their daemon to attribute to True before starting them.
The default value is False. Any daemon threads still running when the main program thread ends will automatically be terminated.
A logical place to do this is right after calling their constructor:
...
Task1 = Thread(target=Up,args=())
Task1.daemon = True
Task2 = Thread(target=Down,args=())
Task2.daemon = True
Task3 = Thread(target=Random,args=())
Task3.daemon = True
Task1.start()
Task2.start()
Task3.start()

Related

Python Threading: Using 2 Light Dependant Resistors (LDR)

I am using a simple code from PiMyLife tutorial to read from a Light Dependant Resistor using a capacitor. This works great..
I then added a 2nd LDR and capacitor, added it to pin 31 and then duplicated the code (the rc_time function and the fuction call) to add an additional Light Dependant Resistor but for some reason the second function call never happens.
#!/usr/local/bin/python
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
#define the pin that goes to the circuit
pin_ldr_one = 29
pin_ldr_two = 31
def rc_time_one (pin_ldr_one):
count_one = 0
#Output on the pin for
GPIO.setup(pin_ldr_one, GPIO.OUT)
GPIO.output(pin_ldr_one, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_one, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_one) == GPIO.LOW):
count_one += 1
return count_one
def rc_time_two (pin_ldr_two):
count_two = 0
#Output on the pin for
GPIO.setup(pin_ldr_two, GPIO.OUT)
GPIO.output(pin_ldr_two, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_two, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_two) == GPIO.LOW):
count_two += 1
return count_two
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print("LDR 1: ",rc_time_one(pin_ldr_one))
print("LDR 2: ",rc_time_two(pin_ldr_two))
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
So I thought I would try threading instead thinking that the 2 function calls were having issues.
So this is the threading code I came up with however this too fails to run the second (in this cask 2nd thread). Any ideas where I am going wrong. Thanks for all your help
#!/usr/local/bin/python
import RPi.GPIO as GPIO
import time
from time import sleep, perf_counter
from threading import Thread
GPIO.setmode(GPIO.BOARD)
#define the pin that goes to the circuit
pin_ldr_one = 29
pin_ldr_two = 31
def rc_time_one (pin_ldr_one = 29):
count_one = 0
#Output on the pin for
GPIO.setup(pin_ldr_one, GPIO.OUT)
GPIO.output(pin_ldr_one, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_one, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_one) == GPIO.LOW):
count_one += 1
print("LDR 1: ",count_one)
return count_one
def rc_time_two (pin_ldr_two = 31):
count_two = 0
#Output on the pin for
GPIO.setup(pin_ldr_two, GPIO.OUT)
GPIO.output(pin_ldr_two, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_two, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_two) == GPIO.LOW):
count_two += 1
print("LDR 2: ",count_two)
return count_two
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
# create two new threads
t1 = Thread(target=rc_time_one)
t2 = Thread(target=rc_time_two)
# start the threads
t1.start()
t2.start()
t1.join()
t2.join()
#print("LDR 1: ",rc_time_one(pin_ldr_one))
#print("LDR 2: ",rc_time_two(pin_ldr_two))
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
Peter

Keyboard input timeout with visible countdown

Good evening,
I want keyboard input with visible timer (time to respond)
My code
import time
import sys
def initial_startup(t):
print('Do you want to continue?')
global input
input = input("Answer yes or no only:" + " ").lower()
while t:
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
print(timer, end="\r")
time.sleep(1)
t -= 1
if input == "yes" or input == "yup":
print("\n\nThanks script is now starting\n\n")
else:
pass
if input == "no" or input == "nope":
print("\nOk as you wish, I'm stopping...\n")
sys.exit(1)
if timer == "00:01":
print("Timeout! try again")
sys.exit(1)
t = 4
initial_startup(int(t))
I'm trying to get keyboard input with timeout and also want to show time below answer yes or no:
Prints timer after input ..
Want this output.
Output:
Do you want to continue?
Answer yes or no:
You have {timer} time left...
If input then continue else sys.exit which is already in code.
Thank you so much for helping to improve this newbie!
To do this you need to move with cursor in the terminal depending on the operating system you are using, it is very tiring and it is not very solid to use the terminal in that way (a static stdout would be easier and safer), what I would do it is an output of this kind obviously you have to use a multithread programming to be able to use the file descriptor simultaneously
import time
import sys
import threading
import time
import sys
def get_input(t):
global stop_threads
while True:
input_cmd = input().lower()
if input_cmd == "yes" or input_cmd == "yup":
print("\n\nThanks script is now starting\n\n")
break
elif input_cmd == "no" or input_cmd == "nope":
print("\nOk as you wish, I'm stopping...\n")
break
stop_threads = True
def initial_startup(t):
print('Do you want to continue?')
t1 = threading.Thread(target=get_input, args=(t,), daemon=True)
t1.start()
while t:
global stop_timeout
global stop_threads
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
prompt = "You have %s time left... Answer yes or no only: " % timer
print(prompt)
sys.stdout.write("\x1b[1A") # cursor up one line
sys.stdout.write("\x1b[2K") # delete the last line
if stop_threads:
sys.exit(1)
time.sleep(1)
t -= 1
if timer == "00:01":
sys.stdout.write("\x1b[2K") # delete the last line
print("Timeout! try again")
sys.exit(1)
stop_threads = False
stop_timeout = False
t = 4
initial_startup(int(t))
Output
Do you want to continue?
You have 00:02 time left... Answer yes or no only:
Ok as you wish, I'm stopping...
Do you want to continue?
You have 00:02 time left... Answer yes or no only:
Timeout! try again
Do you want to continue?
You have 00:05 time left... Answer yes or no only:
Thanks script is now starting

How to get idle time in Linux?

So I'm creating a Password Manager, and as a security feature I wanted to add session time that logs the user out after some time of inactivity (in the example code 3 seconds), and I have this code :
import os
import time
import threading
# Checks what OS you're using
def check_platform():
if os.name == "nt":
platform = "Windows"
else:
platform = "Linux"
return platform
# Starts inactivity timer
def start_timer():
platform = check_platform()
if platform == "Windows":
def timer_start():
while True:
time.sleep(1)
check_if_idle_windows()
thread1 = threading.Thread(target=timer_start)
thread1.start()
elif platform == "Linux":
def timer_start():
while True:
time.sleep(1)
check_if_idle_linux()
thread1 = threading.Thread(target=timer_start)
thread1.start()
# Checks if the user is idle on Windows
def check_if_idle_windows():
import win32api
idle_time = (win32api.GetTickCount() - win32api.GetLastInputInfo()) / 1000.0
if idle_time > 3:
os.system("cls")
print("You have been logged out due to inactivity.")
os._exit(0)
# Checks if the user is idle on Linux
def check_if_idle_linux():
### Code to get idle time here ###
if idle_time > 3:
os.system("clear")
print("You have been logged out due to inactivity.")
os._exit(0)
def random_function_for_main_thread():
while True:
my_string = input("Enter something or stay inactive for 3 seconds : ")
print("You entered something.")
def main():
start_timer()
random_function_for_main_thread()
if __name__ == "__main__":
main()
What can I use to get idle time on Linux?
I tried this and this, and neither of them worked.
Hope my question isn't repeated, thank you.
import os
import time
import threading
# Starts inactivity timer
def start_timer():
platform = check_platform()
if platform == "Windows":
def timer_start():
while True:
time.sleep(1)
check_if_idle_windows()
thread1 = threading.Thread(target=timer_start)
thread1.start()
elif platform == "Linux":
def timer_start():
while True:
time.sleep(1)
check_if_idle_linux()
thread1 = threading.Thread(target=timer_start)
thread1.start()
# Checks what OS you're using
def check_platform():
if os.name == "nt":
platform = "Windows"
else:
platform = "Linux"
return platform
# Checks if the user is idle on Windows
def check_if_idle_windows():
import win32api
idle_time = (win32api.GetTickCount() - win32api.GetLastInputInfo()) / 1000.0
if idle_time > 3:
os.system("cls")
print("You have been logged out due to inactivity.")
os._exit(0)
# Checks if the user is idle on Linux
def check_if_idle_linux():
import subprocess
idle_time = int(subprocess.getoutput('xprintidle')) / 1000 # Requires xprintidle (sudo apt install xprintidle)
if idle_time > 3:
os.system("clear")
print("You have been logged out due to inactivity.")
os._exit(0)
def random_function_for_main_thread():
while True:
my_string = input("Enter something or stay inactive for 3 seconds : ")
print("You entered something.")
def main():
start_timer()
random_function_for_main_thread()
if __name__ == "__main__":
main()

Waiting for a set amount of time before executing action

In the if-else statement below, I want the condition GPIO,input(17) has to be different than 0 for at least 5 second until it prints out "COMMUNICATION IS LOST, PLEASE CHECK". Please help me on this issue
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN)
try:
while True:
if GPIO.input(17):
print "GOOD COMMUNICATION"
else:
print "COMMUNICARION IS LOST, PLEASE CHECK"
sleep (0.1)
finally:
GPIO.cleanup()
try this
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN)
try:
count = 0
while True:
if GPIO.input(17):
count = 0
print "GOOD COMMUNICATION"
else:
if count == 50:
print "COMMUNICATION IS LOST, PLEASE CHECK"
else:
count += 1
sleep(0.1)
finally:
GPIO.cleanup()
If you mean 17 needs to be 0 for 5 seconds that should work
While overkill for this project a thread can help here quite a bit so it's here for anyone interested.
from threading import Thread, Lock
import time
class ListenThread(Thread):
def __init__(self, lock):
Thread.__init__(self)
self._lock = lock # We lock when we work with our status
self._terminating = False
self._status = "CONNECTION NOT MADE"
def run(self):
self._seconds = 0
while True:
if self._terminating:
break
if self._seconds > 5:
self._lock.acquire()
self._status = "COMMUNICATION IS LOST, PLEASE CHECK"
self._lock.release()
elif GPIO.input(17):
self._seconds = 0
self._lock.acquire()
self._status = "GOOD COMMUNICATION"
self._lock.release()
time.sleep(0.5) #interval
self._seconds += 0.5
def status(self):
return self._status
def end(self):
self._lock.acquire()
self._terminating = True;
self._lock.release()
lock = Lock()
worker = ListenThread(lock)
worker.start()
for i in range(0, 25):
# Do other things! When we want to check on the status
# simply ask. Making sure to lock for safety.
lock.acquire()
print worker.status()
lock.release()
time.sleep(0.3)
worker.end() # Make sure to stop the thread!
This will have the same effect except has the usefulness of a thread so we can keep doing work on our main function. (I've replaced the while loop so that it ends but the same could be done as the OP).

how to break a thread function in python

I need a help to stop getCPUtemperature(): function together with robot() function.
def getCPUtemperature():
while True:
res = os.popen('vcgencmd measure_temp').readline()
temp1=int(float(res.replace("temp=","").replace("'C\n","")))
temp2= 9.0/5.0*temp1+32
print temp1,"C", "\n", temp2,"F"
time.sleep(0.5)
if __name__ == '__main__':
try:
#Thread(target = robot).start()
Thread(target = getCPUtemperature).start()
Thread(target = robot).start()
except KeyboardInterrupt:
# CTRL+C exit, turn off the drives and release the GPIO pins
print 'Terminated'
stop_movement()
raw_input("Turn the power off now, press ENTER to continue")
GPIO.cleanup()
quit()strong text
make your child threads daemon and keep the main thread alive to waiting them finish or a ctrl-c pressed.
try the following code:
if __name__ == '__main__':
#Thread(target = robot).start()
t1 = Thread(target = getCPUtemperature)
t1.daemon = True # in daemon mode
t1.start()
t2 = Thread(target = robot)
t2.daemon = True
t2.start()
try:
while threading.active_count() > 1:
time.sleep(1)
except KeyboardInterrupt:
# CTRL+C exit, turn off the drives and release the GPIO pins
print 'Terminated'
stop_movement()
raw_input("Turn the power off now, press ENTER to continue")
GPIO.cleanup()
quit()

Categories