Stopping python using ctrl+c

前端 未结 11 1412
-上瘾入骨i
-上瘾入骨i 2020-11-29 19:44

I have a python script that uses threads and makes lots of HTTP requests. I think what\'s happening is that while a HTTP request (using urllib2) is reading, it\'s blocking a

相关标签:
11条回答
  • 2020-11-29 20:02

    For the record, what killed the process on my Raspberry 3B+ (running raspbian) was Ctrl+'. On my French AZERTY keyboard, the touch ' is also number 4.

    0 讨论(0)
  • 2020-11-29 20:03

    The interrupt process is hardware and OS dependent. So you will have very different behavior depending on where you run your python script. For example, on Windows machines we have Ctrl+C (SIGINT) and Ctrl+Break (SIGBREAK).

    So while SIGINT is present on all systems and can be handled and caught, the SIGBREAK signal is Windows specific (and can be disabled in CONFIG.SYS) and is really handled by the BIOS as an interrupt vector INT 1Bh, which is why this key is much more powerful than any other. So if you're using some *nix flavored OS, you will get different results depending on the implementation, since that signal is not present there, but others are. In Linux you can check what signals are available to you by:

    $ kill -l
     1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
     6) SIGABRT      7) SIGEMT       8) SIGFPE       9) SIGKILL     10) SIGBUS
    11) SIGSEGV     12) SIGSYS      13) SIGPIPE     14) SIGALRM     15) SIGTERM
    16) SIGURG      17) SIGSTOP     18) SIGTSTP     19) SIGCONT     20) SIGCHLD
    21) SIGTTIN     22) SIGTTOU     23) SIGIO       24) SIGXCPU     25) SIGXFSZ
    26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGPWR      30) SIGUSR1
    31) SIGUSR2     32) SIGRTMAX
    

    So if you want to catch the CTRL+BREAK signal on a linux system you'll have to check to what POSIX signal they have mapped that key. Popular mappings are:

    CTRL+\     = SIGQUIT 
    CTRL+D     = SIGQUIT
    CTRL+C     = SIGINT
    CTRL+Z     = SIGTSTOP 
    CTRL+BREAK = SIGKILL or SIGTERM or SIGSTOP
    

    In fact, many more functions are available under Linux, where the SysRq (System Request) key can take on a life of its own...

    0 讨论(0)
  • 2020-11-29 20:03

    On Mac press Ctrl+\ to quit a python process attached to a terminal.

    0 讨论(0)
  • 2020-11-29 20:05

    Ctrl+D Difference for Windows and Linux

    It turns out that as of Python 3.6, the Python interpreter handles Ctrl+C differently for Linux and Windows. For Linux, Ctrl+C would work mostly as expected however on Windows Ctrl+C mostly doesn't work especially if Python is running blocking call such as thread.join or waiting on web response. It does work for time.sleep, however. Here's the nice explanation of what is going on in Python interpreter. Note that Ctrl+C generates SIGINT.

    Solution 1: Use Ctrl+Break or Equivalent

    Use below keyboard shortcuts in terminal/console window which will generate SIGBREAK at lower level in OS and terminate the Python interpreter.

    Mac OS and Linux

    Ctrl+Shift+\ or Ctrl+\

    Windows:

    • General: Ctrl+Break
    • Dell: Ctrl+Fn+F6 or Ctrl+Fn+S
    • Lenovo: Ctrl+Fn+F11 or Ctrl+Fn+B
    • HP: Ctrl+Fn+Shift
    • Samsung: Fn+Esc

    Solution 2: Use Windows API

    Below are handy functions which will detect Windows and install custom handler for Ctrl+C in console:

    #win_ctrl_c.py
    
    import sys
    
    def handler(a,b=None):
        sys.exit(1)
    def install_handler():
        if sys.platform == "win32":
            import win32api
            win32api.SetConsoleCtrlHandler(handler, True)
    

    You can use above like this:

    import threading
    import time
    import win_ctrl_c
    
    # do something that will block
    def work():
        time.sleep(10000)        
    t = threading.Thread(target=work)
    t.daemon = True
    t.start()
    
    #install handler
    install_handler()
    
    # now block
    t.join()
    
    #Ctrl+C works now!
    

    Solution 3: Polling method

    I don't prefer or recommend this method because it unnecessarily consumes processor and power negatively impacting the performance.

    import threading import time

    def work():
        time.sleep(10000)        
    t = threading.Thread(target=work)
    t.daemon = True
    t.start()
    while(True):
        t.join(0.1) #100ms ~ typical human response
    # you will get KeyboardIntrupt exception
    
    0 讨论(0)
  • 2020-11-29 20:07

    If it is running in the Python shell use Ctrl + Z, otherwise locate the python process and kill it.

    0 讨论(0)
  • 2020-11-29 20:12

    On Windows, the only sure way is to use CtrlBreak. Stops every python script instantly!

    (Note that on some keyboards, "Break" is labeled as "Pause".)

    0 讨论(0)
提交回复
热议问题