3

我有一个使用设想框架的客户端-服务器应用程序,我正在使用线程来处理连接,这是代码中的一个标记

    ....
    SocketServer.TCPServer.allow_reuse_address = True        
    self.server = TCPFactory( ( HOST, PORT ), TCPRequestHandler, self.application)               

    self.server_thread = threading.Thread( target = self.server.serve_forever )        

    self.server_thread.setDaemon( True )       
    self.server_thread.start() 

class TCPFactory( SocketServer.ThreadingTCPServer ):    
    def __init__( self, server_address, RequestHandlerClass, application ):
        SocketServer.ThreadingTCPServer.__init__( self, server_address, RequestHandlerClass )
        self.application = application

class TCPRequestHandler( SocketServer.BaseRequestHandler ):
    """"""
    def setup( self ):
        .....

在设想框架中,我调用该open_file( )函数,它给了我们一个弹出窗口,但是当这个窗口出现时,我收到以下错误

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 504, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib/python2.7/SocketServer.py", line 225, in serve_forever
    r, w, e = select.select([self], [], [], poll_interval)
error: (4, 'Interrupted system call')

我该如何处理这个错误?

4

2 回答 2

3

在 Armin Rigo 发表评论后,我修改了 SockeServer.py

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:
                # XXX: Consider using another file descriptor or
                # connecting to the socket to wake this up instead of
                # polling. Polling reduces our responsiveness to a
                # shutdown request and wastes cpu at all other times.
                try:
                        r, w, e = select.select([self], [], [], poll_interval)
                except select.error  as ex:
                        #print ex
                        if ex[0] == 4:
                                continue
                        else:
                                raise  
                if self in r:
                    self._handle_request_noblock()
        finally:
            self.__shutdown_request = False
            self.__is_shut_down.set()
于 2012-11-16T14:16:02.013 回答
0

当我在程序中添加一个小型 httpd 服务器时,我遇到了类似的问题,它接收来自其他进程的各种信号。在玩弄之后,我想出了一个简单的解决方案,可以避免实际修改 stlib 代码,但我认为这有点冒险。我只是将 serve_forever 调用包装在一个循环中,该循环捕获并忽略套接字错误:

def non_int_serve_forever(self, poll_interval=0.5):
   while 1:
        try:
            self.serve_forever(poll_interval=poll_interval)
            break
        except select.error:
            pass

这消除了针对不同版本的 SocketServer.py 需要不同解决方案的风险,但是虽然它现在似乎可以工作,但 serve_forever() 应该可以多次重新启动并不明显。

有什么想法吗?

于 2015-01-16T16:16:54.080 回答