【问题标题】:How to quit an asyncore dispatcher from a handler?如何从处理程序中退出异步调度程序?
【发布时间】:2012-05-07 22:35:58
【问题描述】:

我在docs 中找不到这个,但是我要如何在不使用信号的情况下突破asyncore.loop()

【问题讨论】:

    标签: python asyncore


    【解决方案1】:

    查看源代码后很快就解决了。感谢文档直接链接到源代码!

    有一个 ExitNow 异常,您可以简单地从应用程序中引发,退出循环。

    使用文档中的EchoHandler 示例,我已将其修改为在接收数据时立即退出。

    class EchoHandler(asyncore.dispatcher_with_send):
    
        def handle_read(self):
            data = self.recv(8192)
            if data:
                raise asyncore.ExitNow('Server is quitting!')
    

    另外,请记住,您可以捕获 ExitNow,因此如果您在内部使用它,您的应用不会引发。这是我的一些资料来源:

    def run(config):
        instance = LockServer(config)
        try:
            asyncore.loop()
        except asyncore.ExitNow, e:
            print e
    

    【讨论】:

      【解决方案2】:

      当没有连接时,异步循环也会退出,所以你可以关闭连接。如果您有多个连接正在进行,那么您可以使用 asyncore.close_all()。

      【讨论】:

      • 与抛出异常相比,这个方法感觉像是一个优雅的退出。但是,我想这取决于你想如何处理它。
      【解决方案3】:

      试试这个:

      服务器的一个类(扩展 asyncore.dispatcher):

      class Server(asyncore.dispatcher):
      
          def __init__(self, port):
              asyncore.dispatcher.__init__(self)
      
              self.host = socket.gethostname()
              self.port = port
      
              self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
              self.set_reuse_addr()
              self.bind((self.host, self.port))
              self.listen(5)
              print "[Server] Listening on {h}:{p}".format(h=self.host, p=self.port)
      
          def handle_accept(self):
              pair = self.accept()
              if pair is not None:
                  sock, addr = pair
                  print "[ServerSocket] We got a connection from {a}".format(a=addr)
                  SocketHandler(sock)
      

      另一个用于管理服务器的线程类(扩展线程)...检查 run() 方法,我们在其中调用 asyncore.loop():

      class ServerThread(threading.Thread):
          def __init__(self, port):
              threading.Thread.__init__(self)
              self.server = Server(port)
      
          def run(self):
              asyncore.loop()
      
          def stop(self):
              self.server.close()
              self.join()
      

      现在启动服务器:

      # This is the communication server, it is going to listen for incoming connections, it has its own thread:
      s = ServerThread(PORT)
      s.start()               # Here we start the thread for the server
      print "Server is ready..."
      print "Is ServerThread alive? {t}".format(t=str(s.is_alive()))
      raw_input("Press any key to stop de server now...")
      print "Trying to stop ServerThread..."
      s.stop()
      print "The server will die in 30 seconds..."
      

      你会注意到服务器并没有立即死掉......但它会优雅地死去

      【讨论】:

        【解决方案4】:

        另一种方法是使用 asyncore.loop 调用的 count 参数。然后您可以将 asyncore.loop 包装在其他逻辑中:

        while(i_should_continue()):
            asyncore.loop(count=1)
        

        这不会立即停止打开的连接,也不会提前超时。但这可能是件好事?我在启动监听服务器时使用它。

        【讨论】:

        • 如果您想从“循环外”停止循环,这可能是正确的解决方案。上面的其他解决方案是在循环中停止循环。
        猜你喜欢
        • 2023-03-25
        • 2010-10-10
        • 1970-01-01
        • 2011-06-23
        • 1970-01-01
        • 2019-06-01
        • 1970-01-01
        • 2012-01-08
        • 1970-01-01
        相关资源
        最近更新 更多