我尝试从许多qthread使用xmlrpc客户机。为了确保只有一个线程使用xmlrpc客户机,我用QMutex创建了锁。我的代码:
import sys
import xmlrpclib
import threading
import time
from SimpleXMLRPCServer import SimpleXMLRPCServer
from PyQt4 import QtCore, QtGui
class MM(object):
def __init__(self):
self.lock = QtCore.QMutex()
self.xmlrpc_client = xmlrpclib.ServerProxy('http://localhost:9092')
def __getattr__(self, name):
self.lock.lock()
sys.stderr.write('locked, for %s\n' % name)
print threading.current_thread()
result = self.xmlrpc_client.__getattr__(name)
sys.stderr.write('unlocked by %s\n' % name)
self.lock.unlock()
return result
class Server(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
self.server = None
def run(self):
self.server = SimpleXMLRPCServer(("localhost", 9092), logRequests = False)
def one():
return 1
self.server.register_function(one, 'one')
self.server.serve_forever()
print "SERVER DONE"
class Ask(QtCore.QThread):
def __init__(self, mmInst):
QtCore.QThread.__init__(self)
self.mm = mmInst
self._stopping = False
def run(self):
while not self._stopping:
time.sleep(0.5)
print self.mm.one()
def stop(self):
self._stopping = True
self.wait()
def start_gui():
app = QtGui.QApplication(sys.argv)
server = Server()
server.start()
time.sleep(1)
mm = MM()
print mm.one()
a1 = Ask(mm)
a1.start()
a2 = Ask(mm)
a2.start()
try:
app.exec_()
except keyboardInterrupt:
server.server.shutdown()
if __name__ == "__main__":
start_gui()
但它不起作用,我也不知道为什么。输出如下:
^{pr2}$当只使用一根线时:
$ diff -u test.py.back test.py
--- test.py.back 2012-03-14 01:34:37.666425000 +0100
+++ test.py 2012-03-14 01:33:01.423265000 +0100
@@ -63,8 +63,8 @@
a1 = Ask(mm)
a1.start()
- a2 = Ask(mm)
- a2.start()
+ #a2 = Ask(mm)
+ #a2.start()
try:
app.exec_()
$ python test.py
locked, for one
<_MainThread(MainThread, started -1219930432)>
unlocked by one
1
locked, for one
<_DummyThread(Dummy-1, started daemon -1287918736)>
unlocked by one
1
locked, for one
<_DummyThread(Dummy-1, started daemon -1287918736)>
unlocked by one
1
locked, for one
<_DummyThread(Dummy-1, started daemon -1287918736)>
unlocked by one
1
当使用两个不同的MM实例时,也可以正常工作:
$ diff -u test.py.back test.py
--- test.py.back 2012-03-14 01:34:37.666425000 +0100
+++ test.py 2012-03-14 01:38:47.352862000 +0100
@@ -57,13 +57,13 @@
time.sleep(1)
- mm = MM()
- print mm.one()
+ #mm = MM()
+ #print mm.one()
- a1 = Ask(mm)
+ a1 = Ask(MM())
a1.start()
- a2 = Ask(mm)
+ a2 = Ask(MM())
a2.start()
try:
adam@sabayon /media/Nowy/poker/repos/TestSuite $ python test.py
locked, for one
locked, for one
<_DummyThread(Dummy-1, started daemon -1288275088)><_DummyThread(Dummy-2, started daemon -1298138256)>
unlocked by one
unlocked by one
11
locked, for one
<_DummyThread(Dummy-2, started daemon -1298138256)>
unlocked by one
locked, for one
<_DummyThread(Dummy-1, started daemon -1288275088)>
unlocked by one
1
1
locked, for one
<_DummyThread(Dummy-1, started daemon -1288275088)>
unlocked by one
locked, for one
1<_DummyThread(Dummy-2, started daemon -1298138256)>
unlocked by one
1
我在代码中看到了几个问题,但我马上就要解决的一个问题是,在服务器准备好之前启动客户机。当我先实例化服务器,然后实例化客户机时,我停止了获取连接错误。在
我还删除了spinning while循环,而只是启动了pyqt事件循环。另外,您并没有真正地将MM实例传递给Ask类(对于本例来说,这并不重要,因为您使用的是同一个实例)。在
不管怎么说,下面是我的版本,它似乎起作用了:
更新
在仔细研究了一下之后,我发现这是Python2.7和xmlrpc中的一个bug,它们改变了它创建连接的方式。http://bugs.python.org/issue6907
奇怪的是,这段代码在OSX上的Python2.6/2.7或linux下的Python2.6上不会崩溃。但是对于我来说,在linux下使用Python2.7确实会崩溃。在
当我将锁定机制移到MM实例之外时,它似乎开始在linux上的2.7下工作:
^{pr2}$相关问题 更多 >
编程相关推荐