Python - No se puede matar el hilo principal con KeyboardInterrupt

Estoy haciendo un escáner de puerto multiproceso simple. Analiza todos los puertos en el host y devuelve los puertos abiertos. El problema es interrumpir el escaneo. Lleva mucho tiempo completar una exploración y, a veces, deseo cancelar el programa con C-c mientras se está realizando la exploración. El problema es que la exploración no se detendrá. El subproceso principal está bloqueado en queue.join () y se olvida de KeyboardInterrupt, hasta que todos los datos de la cola se procesan, desbloqueando así el subproceso principal y saliendo del programa con gracia. Todos mis hilos están demonizados, así que cuando el hilo principal muere, ellos deberían morir con él.

Intenté usar la señal lib, sin éxito. La anulación de subprocesos. La clase de subprocesos y el método de adición para una terminación elegante no funcionaron ... El subproceso principal simplemente no recibe KeyboardInterrupt mientras se ejecuta queue.join ()

import threading, sys, Queue, socket

queue = Queue.Queue()

def scan(host):
    while True:
        port = queue.get()

        if port > 999 and port % 1000 == 0:
            print port
        try:
            #sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
            #sock.settimeout(2) #you need timeout or else it will try to connect forever! 
            #sock.connect((host, port))
            #----OR----
            sock = socket.create_connection((host, port), timeout = 2)

            sock.send('aaa')
            data = sock.recv(100)
            print "Port {} open, message: {}".format(port, data)
            sock.shutdown()
            sock.close()
            queue.task_done()
        except:
            queue.task_done()


def main(host):
    #populate queue
    for i in range(1, 65536):
        queue.put(i)
    #spawn worker threads
    for port in range(100):
        t = threading.Thread(target = scan, args = (host,))
        t.daemon = True
        t.start()

if __name__ == '__main__':
    host = ""

    #does input exist?
    try:
        host = sys.argv[1]
    except:
        print "No argument was recivied!"
        exit(1)

    #is input sane?
    try:
        host = socket.gethostbyname(host)
    except:
        print "Adress does not exist"
        exit(2)

    #execute main program and wait for scan to complete
    main(host)
    print "Post main() call!"
    try:
        queue.join()
    except KeyboardInterrupt:
        print "C-C"
        exit(3)

EDITAR:

He encontrado una solución utilizando el módulo de tiempo.

#execute main program and wait for scan to complete
main(host)

#a little trick. queue.join() makes main thread immune to keyboardinterrupt. So use queue.empty() with time.sleep()
#queue.empty() is "unreliable" so it may return True a bit earlier then intented.
#when queue is true, queue.join() is executed, to confirm that all data was processed.
#not a true solution, you can't interrupt main thread near the end of scan (when queue.empty() returns True)
try:
    while True:
        if queue.empty() == False:
            time.sleep(1)
        else:
            break
except KeyboardInterrupt:
    print "Alas poor port scanner..."
    exit(1)
queue.join()

Respuestas a la pregunta(2)

Su respuesta a la pregunta