Stop python program - python

I want to write a program for my network course and i have a socket that listen to receive data if it listen and receive no data i should terminate the program, i use threading.Timer to act like timer and have a line like t = threading.Timer(5, end_data) in my function that listen for receive data but i cant terminate program in end_data that is:
def end_data():
sys.exit()
can any one help me?
i also test below code bud did not terminate running program in terminal :(
def end_data():
try:
sys.exit()
except:
print"exception"
i expect that when stop terminal print Tinas-MacBook-Pro:~ tina$
i'm listening to socket in function named receive not main and when elapse 5 second with no data receiving it will run end_data and seems never return to receive function that part of this function is like below
def receive():
s2 = socket(AF_INET, SOCK_DGRAM)
s2.bind(addr3_2)
global end_call
global base_window
write=open('pictur.jpg','wb')
s = socket(AF_INET, SOCK_DGRAM)
s.bind(addr3)
while(end_call==0):
t = threading.Timer(5, end_data)
t.start()
recv_data, addr = s.recvfrom(3500)#size ro hala badan check kon
t.cancel()
first i decide to set global var end_call after 5 second but it didn't work because it never come back to receive function
some thing that is very interesting for me is if define data_end like:
def end_data():
os._exit
print "Hi"
Hi will print in output :O

Maybe try a setup like this
run_program = True
def end_data() :
global run_program
run_program = False
t = threading.Timer(5, end_data)
t.start()
while run_program:
#do stuff
time.sleep(1)
t.join() #maybe not needed
Make sure you called t.start() :)

To answer your second question, with try, except.
This is the expected behavior per the pydoc:
"Since exit() ultimately “only” raises an exception, it will only exit
the process when called from the main thread, and the exception is not intercepted."
Example:
def end_data():
try:
sys.exit("error!")
except SystemExit, e:
print "Exception caught: ", e.args
print "begin"
end_data()
print "end"
Output:
$ ./test.py
begin
Exception caught: ('error!',)
end

What about using threading Events ?
import threading
event = threading.Event()
def signal_stop():
try:
# do what you have to do
finally:
event.set()
t = threading.Timer(5, signal_stop)
print 'start thread and wait for it'
t.start()
event.wait()
print 'done'

Related

Stop main thread execution immediately if any of the other threads observes an exception in Python

I am trying to have a background thread/process to do some health checks on the system. and the main thread will be performing some other operations.
I want the main thread to stop/fail immediately if the background thread encounters any exceptions.
Most of the solutions I could find online were using a while loop to check if the background thread is_alive(). But that won't fit in this scenario.
Can anyone help out with this?
Something I did with my threads is I had a global variable called "runThreads" or something similar, and I constantly have my threads each check if the value is true. If its false, the thread stops the loop and closes.
def DoSockets():
return RunSockets
def DisableSockets():
global RunSockets
RunSockets = False
def ManageGameSockets():
global MaximumPlayers
global TotalPeople
global ConnectedPeople
global Users
ConnectedPeople = len(Users)-1
while True:
if DoSockets(): # here it checks whether the threads should run or not every time the code loops
print("Waiting for socket connections")
TotalPeople += 1
s.listen(99)
time.sleep(1)
if DoSockets():
try:
conn, addr = s.accept()
print(f"{conn} has connected")
Thread(target=ManageSingleSocket, args=(conn, addr))
ConnectedPeople += 1
TotalPeople += 1
except OSError:
pass
else:
break # if it shouldn't run then break the loop
print()
"Stopping socket hosting" # this is the last line and consequently should close the function/thread when it finishes
assuming that is how threads work. I also just read that sys.exit() can close a specific thread. Read the answer from this: https://stackoverflow.com/questions/4541190/how-to-close-a-thread-from-within#:~:text=If%20sys.,will%20close%20that%20thread%20only.

How to terminate main program when thread ends? Still getting waiting for process to detach in python?

I am having a main program which is defined like this:
main.py
def main():
try:
registry.start_server()
except:
print("Shutting down the program")
pass
if __name__ == '__main__':
main()
registry.start_server() is the method in another module which looks like this:
def start_server():
t_server = threading.Thread(target=server.start)
t_server.start()
try:
t_server.join()
except KeyboardInterrupt:
print("Error")
raise ValueError
finally:
fp.close()
server.start is the method in another module which does some listening work in a while(True) manner. I am not sure how to stop the whole program when clicking Stop in PyCharm which is Ctrl + C (Signal). I tried with Event but without success. I get to the main.py by raising an exception when the signal gets caught but that does not terminate the whole program. It shows Waiting for program to detach. The only way is to use SIGKILL. I don't understand where does the program keeps hanging? I have also tried calling sys.exit(0) when the signal gets caught and creating the thread as Deamon but that didnt help either.
EDIT
While True method in another module
def start(self, event):
try:
while True:
if event.is_set():
if self.pubsub.channels:
print("It enters here")
message = self.pubsub.get_message(True)
if message:
.
.
.
else:
return
To solve the problem, all you need to do is:
let the child-thread exit, and
let main thread join the child-thread.

Signal handling in loop with sleep python 2.7

This might be a simple situation that I expect many would have encountered it.
I have a simple python program that does something and sleeps for sometime in an infinite loop. I want to use signals to make this program exit gracefully on a SIGHUP. Now when a signal is sent to callee.py when it is in sleep, the program exits immediately whereas I expect it to finish the sleep and then exit.
Is there any workaround to bypass this behavior? I am also open to any other methods through which I can achieve this.
Note: This works as expected with python3 but I cannot port my existing module which is in python 2.7 to 3 now.
This is the code I have:
callee.py
stop_val = False
def should_stop(signal, frame):
print('received signal to exit')
global stop_val
stop_val = True
def main():
while not stop_val:
signal.signal(signal.SIGTERM, should_stop)
# do something here
print('Before sleep')
time.sleep(300)
print('after sleep')
caller.py
pid = xxx;
os.system('kill -15 %s' % pid)
I ran into the same issue today. Here is a simple wrapper that mimicks the python3 behaviour:
def uninterruptable_sleep(seconds):
end = time.time()+seconds
while True:
now = time.time() # we do this once to prevent race conditions
if now >= end:
break
time.sleep(end-now)

Python Multithreading - where does keyboard interrupt go

I'm having trouble with some seemingly simple code which basically starts a thread to read a serial device, and then in the main thread writes some data to the device. The intended shutdown mechanism is a keyboard interrupt, but that doesn't seem to be caught how I expect.
readData = True
dev = serial.Serial('/dev/ttyX', 115200)
readThread = threading.Thread(target=read_loop, args=())
readThread.start()
send_loop()
def read_loop():
while readData:
try:
print dev.read(2)
except Exception, e:
print 'Continue'
dev.close()
def send_loop():
global readData
for i in xrange(5):
try:
dev.write('a')
time.sleep(1)
except Exception,e:
break
readData = False
readThread.join()
A keyboard interrupt, or any other external signal, always goes to the main thread only -- not to sub-threads. If you want everything to stop when the main thread terminates, make sub-threads daemons, so they won't keep the whole process alive by themselves!

unable to create a thread in python

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()

Categories