<p>所以你可以定义:</p>
<pre><code>def run ( self ):
server = stoppableHttpServer(('',self.Port), self.CMRequestHandler )
server.serve_forever()
server.socket.close()
</code></pre>
<p>在这里,实例中不保留对变量<code>server</code>的引用。这是一个问题,因为它意味着不可能更改下面类中的<code>self.stop</code>标志:</p>
^{pr2}$
<p>当您执行<code>server_forever</code>方法时,它会阻塞它的线程。由于没有保留对其父实例的引用,因此无法设置<code>self.stop = True</code>。实际上,在代码中没有尝试这样做,所以套接字很可能挂起。如果<code>handle_request</code>正在阻塞(如果不设置超时,这也是一个问题)。在</p>
<p>您应该注意到<code>serve_forever</code>的默认实现可以用<code>server.shutdown</code>停止,因此检查<code>self.stop</code>标志的状态是多余的。在</p>
<p>我建议将您的<code>LaunchHTTPServer</code>类更新为如下内容:</p>
<pre><code># as the only part of the code that needs to run as a thread is the serve_forever method
# there is no need to have this class as a thread
class LaunchHTTPServer (object):
def __init__ ( self, sPort, CMRequestHandler ):
self.notifyWindow = None
self.Port = sPort
self.CMRequestHandler = CMRequestHandler
self.bExecute = True
self.server = None
self.server_thread = None
def start ( self ):
# Here you can use the default HTTPServer implementation, as the server is already stoppable
self.server = BaseHTTPServer.HTTPServer(('',self.Port), self.CMRequestHandler )
self.server_thread = Thread(target=self.server.serve_forever)
self.server_thread.start()
def stop( self ):
try:
self.server.shutdown()
self.server.socket.close()
self.server_thread.join()
self.server,self.server_thread = None,None
except Exception as error:
pass # catch and raise which ever errors you desire here
def getExecute ( self ):
return ( self.bExecute )
def endThread ( self ):
pass
</code></pre>
<p>通过上面的设置,您现在可以从键盘捕捉Ctrl-C中断,并确保调用实例的<code>stop</code>方法来干净地关闭套接字并退出。在</p>