0

I want to handle the signal.SIGINT from a CTRL-C keyboard event to safely exit my processes before exiting the main thread. I know how to do this using a signal handler, but if any of my threads or processes imports the module, nltk.corpus.stopwords that somehow prevents the signal handler from running. What I assume is going on, is that the module is so large that it is still being loaded when the signal is produced, but I'm not one-hundred percent sure.

Here is a minimal complete and verifiable example

The following code works as expected.

import signal
import time
import sys

def signal_handler(signum, frame):
    print "Safely exiting processes"
    for p in proc:
        print p
    sys.exit(0)

proc = [1, 2, 3, 4]
signal.signal(signal.SIGINT, signal_handler)
print('Press Ctrl+C to interrupt download')
while(True):
    time.sleep(1)
    print 'wait'

It produces the expected output:

> Press Ctrl+C to interrupt download 
> wait
> wait
> Safely exiting processes
> 1
> 2
> 3
> 4

Adding the import statement

from nltk.corpus import stopwords 

Changes the output to this error message:

> Press Ctrl+C to interrupt download 
> wait
> wait
> forrtl: error (200): program aborting due to control-C event
> Image    PC    Routine    Line    Source
> 
> kernel32.dll   0000000077544AE3   Unknown    Unknown    Unknown
> kernel32.dll   00000000775059ED   Unknown    Unknown    Unknown
> ntdll.dll    000000007763C541   Unknown    Unknown    Unknown

Ctrl-C crashes Python after importing scipy.stats is a very similar question but the described behavior is slightly different and the accepted answer does not work for me.

  • The accepted answer also reports getting the same error message using the time module. I have no issue with the time module.
  • The accepted answer's solution simply moves the import statements after the handler initialization. This doesn't remove the error for me, maybe because they are using win32api.SetConsoleCtrlHandler instead of signal.signal
Community
  • 1
  • 1
Cecilia
  • 4,512
  • 3
  • 32
  • 75
  • I'm not a windows guy but I'm not sure that what you're seeing is wrong. You are hard exiting the process with a sys.exit. Another option is to inspect the frame in the signal handler and gracefully exit your looping thread using a semaphore – Will May 06 '15 at 18:02
  • @Will, the code above returns the expected result if the nltk module is not included. Can you explain in more detail why you think importing the nltk module should change the expected behavior? – Cecilia May 06 '15 at 18:07
  • Sorry I misread the question. Seems someone else is registering the handler too I suspect – Will May 06 '15 at 18:18
  • This might help: http://stackoverflow.com/questions/15457786/. There are quite a few decent hits on google for this, looks like a handler registration order problem. – Will May 06 '15 at 18:19
  • @Will Unfortunately, that solution didn't work for me. At least not with `signal.signal`. I'll look into using `win32api.SetConsoleCtrlHandler` instead. – Cecilia May 06 '15 at 20:18
  • I've edited [my answer](http://stackoverflow.com/a/15472811/205580). FYI, Windows itself has no notion of signals. The Windows console has control events and registered control handlers. The C runtime installs a control handler to implement `SIGINT`, as required by the ISO C standard. Windows Python uses the CRT's implementation of signals. The issue you're having is at the underlying console control event layer. Hopefully my revised answer helps to clarify this. – Eryk Sun May 07 '15 at 05:36

0 Answers0