【问题标题】:Stopping socketserver.ThreadingMixIn in python在python中停止socketserver.ThreadingMixIn
【发布时间】:2014-07-23 12:03:46
【问题描述】:

我在 Python 3.4 中扩展 socketserver.ThreadingMixIn 以构建我自己的线程服务器,同时保持原始回调仅用于记录海豚。 激活和创建非常简单,根据 python 文档,我遇到的问题是使用server.shutdown() 停止该服务器。它卷曲并且不退出。我需要在不使用 ctrl-c 的情况下关闭该服务器,因为它还会涉及该服务器的一些 GUI。

基础服务器:

class ServerBasic(socketserver.ThreadingMixIn,socketserver.TCPServer):

logging.basicConfig(level=logging.DEBUG,format='%(name)s: %(message)s',)   

def __init__(self, log_name,server_address, handler_class=ThreadedRequestHandler):
    self.logger = logging.getLogger(log_name)
    self.logger.debug('__init__')
    socketserver.TCPServer.__init__(self, server_address, handler_class)
    return

def server_activate(self):
    self.logger.debug('server_activate')
    socketserver.TCPServer.server_activate(self)
    return

def serve_forever(self):
    self.logger.debug('waiting for request')
    self.logger.info('Handling requests, press <Ctrl-C> to quit')
    while True:
        self.handle_request()
    return

扩展类:

class ManagerServer(PIRServerBasic):


def __init__(self, log_name, handler_class=T_ManagerRequestHandler):
    self.tup_socket = (ipAddress, WELCOME_PORT) # tuple of the address and port
    self.log_name = log_name
    return ServerBasic.__init__(self, log_name, self.tup_socket, handler_class=handler_class)

以及它是如何创建和运行的:

o_serverManager = ManagerServer('Manager_Server', T_ManagerRequestHandler) 
t_managerServer = threading.Thread(target=o_serverManager.serve_forever)
t_managerServer.daemon = True 
t_managerServer.start()

sleep(15)
o_serverManager.shutdown()

关闭命令后程序卡住了。

【问题讨论】:

    标签: python multithreading serversocket asyncsocket


    【解决方案1】:

    在您覆盖 serve_forever 方法时,您已删除在关闭请求中中断 while 循环的条件。原来的方法是这样的:

    def serve_forever(self, poll_interval=0.5):
        """Handle one request at a time until shutdown.
    
        Polls for shutdown every poll_interval seconds. Ignores
        self.timeout. If you need to do periodic tasks, do them in
        another thread.
        """
        self.__is_shut_down.clear()
        try:
            while not self.__shutdown_request:
                r, w, e = _eintr_retry(select.select, [self], [], [],
                                       poll_interval)
                if self in r:
                    self._handle_request_noblock()
        finally:
            self.__shutdown_request = False
            self.__is_shut_down.set()
    

    您需要在覆盖中实现类似的系统,以查找设置的__shutdown_request 标志并采取适当的措施。这也要求您的处理程序是非阻塞的。

    【讨论】:

    • 您的回答解决了我的问题。我没有查看该回调的原始实现,它确实阻止了我的主线程退出。谢谢
    猜你喜欢
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 2016-12-10
    • 2021-11-23
    • 2020-09-19
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多