Last active
July 13, 2018 12:24
-
-
Save stuaxo/9308767 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| Interuptible cmd.Cmd. | |
| This is useful if you need a long running thread like a GUI event loop. | |
| The trick is to run the cmd.Cmd shell in the main thread, and your main | |
| loop in another background thread. | |
| The app needs to be able to quit from both the main thread and main loop. | |
| If quitting from the mainloop (other thread), it sends SIGINT, which | |
| will interrupts the shell with KeybaordInterrupt. | |
| If quitting from the shell (main thread), then the a variable in the | |
| mainloop is set which then quits. | |
| """ | |
| import cmd | |
| import os | |
| import time | |
| import sys | |
| import signal | |
| import threading | |
| run_app_loop = True | |
| def mainloop(): | |
| global run_app_loop | |
| # This could run your main GUI thread. or other long running code | |
| iterations = 0 | |
| while run_app_loop: | |
| time.sleep(1) # Simulate doing something. | |
| # On the 7th run simulate a quit triggered in this thread | |
| iterations += 1 | |
| if iterations == 7: | |
| print '\nSimulating quit event' | |
| run_app_loop = False | |
| print '\nQuit app thread.' | |
| os.kill(os.getpid(), signal.SIGINT) # Tell the other thread to quit with SIGINT | |
| class TestCmd(cmd.Cmd): | |
| def do_quit(self, line): | |
| return self.do_EOF("") | |
| def do_EOF(self, line): | |
| global run_app_loop | |
| print 'Telling other thread to quit.' | |
| run_app_loop = False | |
| return True | |
| t = threading.Thread(target=mainloop) | |
| t.start() | |
| try: | |
| print 'Will quit automatically in 8 seconds, interrupting cmd.Cmd' | |
| shell = TestCmd() | |
| shell.do_help("") | |
| shell.cmdloop() | |
| run_app_loop = False | |
| t.join() | |
| except KeyboardInterrupt: | |
| if run_app_loop: | |
| raise | |
| else: | |
| print '\nBye' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment