I'm following a tutorial on simple threading. They give this example and when I try to use it I'm getting unintelligible errors from the interpreter. Can you please tell me why this isn't working? I'm on WinXP SP3 w/ Python 2.6 current
import thread
def myfunction(mystring,*args):
print mystring
if __name__ == '__main__':
try:
thread.start_new_thread(myfunction,('MyStringHere',1))
except Exception as errtxt:
print errtxt
Executing this results in::
Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:
The information missing in the error is actually missing in the output.
The problem is that your main thread has quit before your new thread has time to finish. The solution is to wait at your main thread.
import thread, time
def myfunction(mystring,*args):
print mystring
if __name__ == '__main__':
try:
thread.start_new_thread(myfunction,('MyStringHere',1))
except Exception, errtxt:
print errtxt
time.sleep(5)
As a side note, you probably want to use the threading module. Your main thread will wait for all of those types of threads to be closed before exiting:
from threading import Thread
def myfunction(mystring,*args):
print mystring
if __name__ == '__main__':
try:
Thread(target=myfunction, args=('MyStringHere',1)).start()
except Exception, errtxt:
print errtxt
You need to wait until your Thread finishes its work, so you have to use Thread.join() :
from threading import Thread
def myfunction(mystring,*args):
print mystring
if __name__ == '__main__':
try:
t = Thread(None,myfunction,None,('MyStringHere',1))
t.start()
t.join()
except Exception as errtxt:
print errtxt
import thread
def myfunction(mystring,*args):
print mystring
if __name__ == '__main__':
try:
thread.start_new_thread(myfunction,('MyStringHere',1))
except Exception as errtxt:
print errtxt
while 1:
pass
Put while loop at last then it will work for you.
I tried it in Python 2.5 on a mac, after changing
except Exception as errtxt:
to
except Exception, errtxt:
The program did not throw an exception but also did not print anything. Not sure if that is helpful, but I do find it curious...
When I ran this code in Python 2.6 it worked, is it possible you have open threads already that are locked on the function? I recommend closing Python completely, checking your running processes to make sure nothing of yours is running and try again.
Related
from google.cloud import pubsub_v1
def run():
# created full_* vars here...
future = subscriber.subscribe(full_subscription, print_and_ack_message)
try:
future.result()
except KeyboardInterrupt: # this doesn't work for some reason...
logging.info("Subscription terminated...")
future.cancel()
except BaseException as exc:
logging.info("Other %s", type(exc))
if __name__ == '__main__':
run()
The above code cannot be interrupted on macOS, zsh, iTerm and pyenv-virtualenv with python 2.7.15, for some reason?
CTRL+C fails from the terminal with this code; nothing happens, only ^C is visible in the output and it does neither terminate nor print anything. What is wrong?
I'm following the docs
You don't need to use the result method here:
The subscriber is non-blocking, so we must keep the main thread from exiting to allow it to process messages in the background.
def run():
future = subscriber.subscribe(full_subscription, print_and_ack_message)
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
future.cancel()
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.
I would like the user to use control-c to close a script, but when control-c is pressed it shows the error and reason for close (which make sense). Is there a way to have my own custom output to the screen rather than what is shown? Not sure how to handle that specific error.
You could use try..except to catch KeyboardInterrupt:
import time
def main():
time.sleep(10)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print('bye')
use the signal module to define a handler for the SIGINT signal:
import signal
import sys
def sigint_handler(signal_number, stack_frame):
print('caught SIGINT, exiting')
sys.exit(-1)
signal.signal(signal.SIGINT, sigint_handler)
raw_input('waiting...')
For general purpose code, handling the KeyboardInterrupt should suffice. For advanced code, such as threading, it is a whole different story. Here's a simple example.
http://docs.python.org/2/library/exceptions.html#exceptions.KeyboardInterrupt
try:
while 1:
x = raw_input("Type something or press CTRL+C to end: ")
print repr(x)
except KeyboardInterrupt:
print "\nWe're done here."
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()
I want to catch KeyboardInterrupt globally, and deal with it nicely. I don't want to encase my entire script in a huge try/except statement. Is there any way to do this?
You could change sys.excepthook if you really don't want to use a try/except.
import sys
def my_except_hook(exctype, value, traceback):
if exctype == KeyboardInterrupt:
print "Handler code goes here"
else:
sys.__excepthook__(exctype, value, traceback)
sys.excepthook = my_except_hook
If this is a script for execution on the command line, you can encapsulate your run-time logic in main(), call it in an if __name__ == '__main__' and wrap that.
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print 'Killed by user'
sys.exit(0)
You can also use signal like this:
import signal, time
def handler(signum, frame):
print 'I just clicked on CTRL-C '
signal.signal(signal.SIGINT, handler)
print "waiting for 10 s"
time.sleep(10)
Output:
waiting for 10 s
^CI just clicked on CTRL-C
N.B: Don't mix the use of signal with threads.
Does your script have a function you call to start it?
main()
then just do:
try:
main()
except:
...
If you don't have a main but just a huge script that runs line-by-line, then you should put it in a main.
There's no other way to do this, apart from encasing your entire script in a main() function and surrounding that with a try..except block - which is pretty much the same:
def main():
# Your script goes here
pass
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
# cleanup code here
pass