【问题标题】:Killing multi-threaded SocketServer杀死多线程 SocketServer
【发布时间】:2023-04-06 21:49:01
【问题描述】:

我试图弄清楚为什么我不能通过 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 杀死整个脚本的最佳方法是什么。 任何帮助将不胜感激!

谢谢

【问题讨论】:

  • 你有四个相同的类有什么原因吗?此外,如果没有特殊权限,您将无法收听端口239
  • 概念是绑定4个端口,尝试用crtl -c杀死服务器。
  • 您仍然可以对所有端口使用相同的请求处理程序类,无需为每个端口创建 单独的类,除非它们执行不同的操作(您不这样做) )。
  • 有 7 台这样的服务器,在不同的端口上回答不同的查询。
  • 看看signal 模块。您将能够捕捉到 SIGINT 并做出适当的反应。

标签: python multithreading python-2.7 kill


【解决方案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 上关闭属于服务器(另一种解决方案)。

【讨论】:

  • 一位朋友告诉我,您也可以使用Thread.setDeamon(..., True) 来避免关闭问题。
【解决方案2】:

创建线程时,将它们设置为守护进程:

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

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

基于here 中的python 文档:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 2017-01-22
    • 2016-07-10
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多