【问题标题】:Running SimpleXMLRPCServer in separate thread and shutting down在单独的线程中运行 SimpleXMLRPCServer 并关闭
【发布时间】:2010-10-04 21:28:39
【问题描述】:

我有一个类,我希望通过 Python 中的 SimpleXMLRPCServer 进行测试。我设置单元测试的方式是创建一个新线程,并在其中启动 SimpleXMLRPCServer。然后我运行了所有的测试,最后关机了。

这是我的服务器线程:

class ServerThread(Thread):
    running = True
    def run(self):
        self.server = #Creates and starts SimpleXMLRPCServer

        while (self.running):
            self.server.handle_request()

    def stop(self):
        self.running = False
        self.server.server_close()

问题是,调用 ServerThread.stop(),然后调用 Thread.stop() 和 Thread.join() 不会导致线程正确停止,如果它已经在等待 handle_request 中的请求。而且由于这里似乎没有我可以使用的任何中断或超时机制,我不知道如何干净地关闭服务器线程。

【问题讨论】:

    标签: python multithreading simplexmlrpcserver


    【解决方案1】:

    这是我的方式。向自己发送 SIGTERM。 (为我工作)

    服务器代码

    import os
    import signal
    import xmlrpc.server
    
    server = xmlrpc.server.SimpleXMLRPCServer(("0.0.0.0", 8000))
    server.register_function(lambda: os.kill(os.getpid(), signal.SIGTERM), 'quit')
    server.serve_forever()
    

    客户端代码

    import xmlrpc.client
    
    c = xmlrpc.client.ServerProxy("http://localhost:8000")
    try:
        c.quit()
    except ConnectionRefusedError:
        pass
    

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,经过数小时的研究,我解决了这个问题,方法是从使用我自己的 handle_request() 循环切换到 serve_forever() 来启动服务器。

      serve_forever() 像你一样开始一个内部循环。这个循环可以通过调用 shutdown() 来停止。停止循环后,可以使用 server_close() 停止服务器。

      我不知道为什么会这样,而 handle_request() 循环却没有,但它确实有效;P

      这是我的代码:

      from threading import Thread
      from xmlrpc.server import SimpleXMLRPCServer
      from pyWebService.server.service.WebServiceRequestHandler import WebServiceRquestHandler
      
      class WebServiceServer(Thread):
          def __init__(self, ip, port):
              super(WebServiceServer, self).__init__()
              self.running = True
              self.server = SimpleXMLRPCServer((ip, port),requestHandler=WebServiceRquestHandler)
          self.server.register_introspection_functions()
      
          def register_function(self, function):
              self.server.register_function(function)
      
          def run(self):
              self.server.serve_forever()
      
          def stop_server(self):
              self.server.shutdown()
              self.server.server_close()
      
      print("starting server")
      webService = WebServiceServer("localhost", 8010)
      webService.start()
      print("stopping server")
      webService.stop_server()
      webService.join()
      print("server stopped")
      

      【讨论】:

      • 更新(python 2.7.9):我试过了,没有必要导入WebServiceRequestHandler(或提供处理程序给requestHandler)。
      【解决方案3】:

      两个建议。

      建议一是使用单独的进程而不是单独的线程。

      • 创建一个独立的 XMLRPC 服务器程序。

      • subprocess.Popen() 开头。

      • 测试完成后杀死它。在标准操作系统(不是 Windows)中,kill 效果很好。然而,在 Windows 中,没有琐碎的 kill 函数,但有这方面的秘诀。

      另一个建议是在您的 XMLRPC 服务器中设置一个导致服务器自毁的功能。您定义一个函数,该函数调用 sys.exit()os.abort() 或引发类似的异常以停止进程。

      【讨论】:

      • 我会记住这个方法,以备不时之需。我更喜欢跨平台解决方案,因此关闭方法似乎最合理。我通过发送一个虚拟请求来修复它,该请求将终止线程,因为 self.running 将是错误的。
      • 子进程是跨平台的。子流程加上自毁方法效果最好。
      猜你喜欢
      • 1970-01-01
      • 2013-09-26
      • 2019-08-12
      • 2013-01-25
      • 2012-05-20
      • 1970-01-01
      • 2015-01-24
      • 2011-04-21
      • 2011-06-29
      相关资源
      最近更新 更多