SimpleXMLRPCServer、wxPython 和线程 - 如何停止?
这里有一个示例程序,说明了我遇到的问题。这个程序启动了一个wxPython应用程序,并在一个线程中启动了一个SimpleXMLRPCServer。这一切都运行得很好。我的问题是,我无法关闭SimpleXMLRPCServer线程,因为它在handle_request()这个调用上被阻塞了。我是在Windows XP机器上开发的(我不知道在Linux上是否会出现同样的问题)。
import wx
import SimpleXMLRPCServer
import threading
class myServerFunction(object):
def result(self):
return "Hello World"
class serverThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.timeToQuit = threading.Event()
self.timeToQuit.clear()
def stop(self):
self.server.server_close()
self.timeToQuit.set()
def run(self):
self.server = SimpleXMLRPCServer.SimpleXMLRPCServer( ("localhost", 8000), logRequests=False )
self.server.register_instance( myServerFunction )
#self.server.serve_forever()
while not self.timeToQuit.isSet():
self.server.get_request()
self.server.handle_request()
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.serverThread = serverThread()
self.serverThread.start()
wx.EVT_CLOSE(self, self.OnExit)
def OnExit(self, event):
print "Server should turn off!"
self.serverThread.stop()
self.Destroy()
app = wx.PySimpleApp(0)
frame_1 = MyFrame(None, -1, "")
app.SetTopWindow(frame_1)
frame_1.Show()
app.MainLoop()
app.Exit()
根据我在网上的研究,我发现杀死线程是个麻烦的问题。
看起来我的选择是使用twisted或processing模块……还有其他解决方案吗?
这里有一篇我觉得特别有趣的帖子,尽管我认为它可能对我没有帮助,因为我可能是在socket上被阻塞,而不是在Python中: http://www.velocityreviews.com/forums/t330554-kill-a-thread-in-python.html
2 个回答
0
我不确定这是否还有人关心,但如果把
while not self.timeToQuit.isSet():
self.server.handle_request()
替换成
try:
self.server.serve_forever()
except:
print( "SimpleXMLRPCServer stopped" )
那么代码就能正常工作了。使用这些代码行时,self.server.server_close() 会在 server_forever() 里引发一个错误,这样会导致它退出并结束线程。
1
这个方法有效。感谢我上面评论中的链接。
import wx
import SimpleXMLRPCServer
import threading
import xmlrpclib
class myServerFunction(object):
def result(self):
print "myServerFunction"
return "Hello World"
class serverThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.timeToQuit = threading.Event()
self.timeToQuit.clear()
def stop(self):
self.server.server_close()
self.timeToQuit.set()
def run(self):
print "runing"
self.server = SimpleXMLRPCServer.SimpleXMLRPCServer( ("localhost", 8000), logRequests=False )
self.server.register_instance( myServerFunction() )
while not self.timeToQuit.isSet():
self.server.handle_request()
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.serverThread = serverThread()
self.serverThread.start()
wx.EVT_CLOSE(self, self.OnExit)
self.server = xmlrpclib.Server( "http://localhost:8000" )
def OnExit(self, event):
print "Server should turn off!"
self.serverThread.stop()
print self.server.result() # dummy call to unlock the socket deadlock
self.Destroy()
app = wx.PySimpleApp(0)
frame_1 = MyFrame(None, -1, "")
app.SetTopWindow(frame_1)
frame_1.Show()
app.MainLoop()
app.Exit()