views:

158

answers:

2

Hello, everyone

I cannot get a way to terminate a thread that is hung in a socket.recvfrom() call. For example, ctrl+c that should trigger KeyboardInterrupt exception can't be caught. Here is a script I've used for testing:

from socket import *
from threading import Thread
from sys import exit

class TestThread(Thread):
    def __init__(self,host="localhost",port=9999):
        self.sock = socket(AF_INET,SOCK_DGRAM)
        self.sock.bind((host,port))
        super(TestThread,self).__init__()

    def run(self):
        while True:
            try:
                recv_data,addr = self.sock.recvfrom(1024)
            except (KeyboardInterrupt, SystemExit):
                sys.exit()

if __name__ == "__main__":
    server_thread = TestThread()
    server_thread.start()
    while True: pass

The main thread (the one that executes infinite loop) exits. However the thread that I explicitly create, keeps hanging in recvfrom().

Please, help me resolve this.

A: 

You should open a pipe from the main thread to the network thread and 'select' on both the socket and the pipe. When you want to terminate the network thread, just send a byte through the pipe from the main thread and act accordingly in the network thread.

Just my 2 cents.

pau.estalella
+1  A: 

Keyboard interrupts are always caught on the main thread -- never on "child" threads. To avoid server_thread keeping the process alive when the main thread exits, do

server_thread.daemon = True

before you call server_thread.start().

BTW, your while True: pass in the main thread is needlessly burning CPU cycles. You should at least change it to something like while True: time.sleep(1.0). But that doesn't change the semantics of your code -- just gets it down from 99% CPU or so, to (I'd guess) < 5%;-).

Alex Martelli
Yahoo!!! That works. Thanks a lot.>your while True: pass is needlessly burning CPU cycles.That was just to illustrate the problem keeping the code to the minimum.
Dihlofos