1

我试图弄清楚为什么我不能通过 CRTL-C 杀死我的多线程 SocketServer。

基本上我有:

import SocketServer,threading

class TEST(SocketServer.BaseRequestHandler):
    def server_bind(self):
        self.socket.setsockopt(SOL_SOCKET, SO_REUSEADDR,SO_REUSEPORT, 1)
        self.socket.bind(self.server_address)
        self.socket.setblocking(0)

    def handle(self):
        request, socket = self.request
        data = request
        if data[0] == "\x01":
           buff = "blablabla"
           socket.sendto(str(buff), self.client_address)

class TEST1(SocketServer.BaseRequestHandler):
    def server_bind(self):
        self.socket.setsockopt(SOL_SOCKET, SO_REUSEADDR,SO_REUSEPORT, 1)
        self.socket.bind(self.server_address)
        self.socket.setblocking(0)

    def handle(self):
        request, socket = self.request
        data = request
        if data[0] == "\x01":
           buff = "blablabla"
           socket.sendto(str(buff), self.client_address)

class TEST2(SocketServer.BaseRequestHandler):
    def server_bind(self):
        self.socket.setsockopt(SOL_SOCKET, SO_REUSEADDR,SO_REUSEPORT, 1)
        self.socket.bind(self.server_address)
        self.socket.setblocking(0)

    def handle(self):
        request, socket = self.request
        data = request
        if data[0] == "\x01":
           buff = "blablabla"
           socket.sendto(str(buff), self.client_address)

class TEST3(SocketServer.BaseRequestHandler):
    def server_bind(self):
        self.socket.setsockopt(SOL_SOCKET, SO_REUSEADDR,SO_REUSEPORT, 1)
        self.socket.bind(self.server_address)
        self.socket.setblocking(0)

    def handle(self):
        request, socket = self.request
        data = request
        if data[0] == "\x01":
           buff = "blablabla"
           socket.sendto(str(buff), self.client_address)

def serve_thread_udp(host, port, handler):
    server = SocketServer.UDPServer((host, port), handler)
    server.serve_forever()

def serve_thread_tcp(host, port, handler):
    server = SocketServer.TCPServer((host, port), handler)
    server.serve_forever()

def main():
    try:
      threading.Thread(target=serve_thread_tcp,args=('', 4045,TEST)).start()
      threading.Thread(target=serve_thread_tcp,args=('', 239,TEST1)).start()
      threading.Thread(target=serve_thread_udp,args=('', 1246,TEST2)).start()
      threading.Thread(target=serve_thread_tcp,args=('', 12342,TEST3)).start()
    except KeyboardInterrupt:
        os._exit()

if __name__ == '__main__':
    try:
        main()
    except:
        raise

我试图了解我做错了什么以及能够通过 crtl-c 杀死整个脚本的最佳方法是什么。任何帮助将不胜感激 !

谢谢

4

2 回答 2

1

这是一个解决方案:

def main():
    import thread
    try:
      thread.start_new(serve_thread_tcp, ('', 4045,TEST))
      thread.start_new(serve_thread_tcp,('', 239,TEST1))
      thread.start_new(serve_thread_udp,('', 1246,TEST2))
      thread.start_new(serve_thread_tcp,('', 12342,TEST3))
    except KeyboardInterrupt:
        os._exit()

if __name__ == '__main__':
    try:
        main()
    except:
        raise
    raw_input()

要关闭服务器,您可以键入 return 或关闭标准输入。

问题在于Thread在所有关闭之前不允许关闭应用程序的类Threads

serve_forever() 将不会结束,直到您在 KeyboardInterrupt 上关闭属于服务器(其他解决方案)。

于 2012-09-08T15:11:30.347 回答
1

创建线程时,将它们设置为 daemon :

Thread.__init__(self)
self.setDaemon(True)

这样,当您杀死主线程时,所有线程都将终止。

基于此处的python文档:

可以将线程标记为“守护线程”。这个标志的意义在于,当只剩下守护线程时,整个 Python 程序就退出了。初始值继承自创建线程。可以通过 daemon 属性设置标志。

于 2012-09-08T15:53:47.753 回答