qthreads 및 XMLRPC 클라이언트
-
13-12-2019 - |
문제
많은 qthreads에서 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()
.
하지만 작동하지 않아 왜 잘 모르겠습니다.출력이 있습니다 :
locked, for one
<_MainThread(MainThread, started 1648)>
unlocked by one
1
locked, for one
<_DummyThread(Dummy-1, started daemon 356)>
unlocked by one
locked, for one
<_DummyThread(Dummy-2, started daemon 1480)>
unlocked by one
Traceback (most recent call last):
File "H:\poker\repos\TestSuite\test.py", line 46, in run
print self.mm.one()
File "C:\Python27\lib\xmlrpclib.py", line 1224, in __call__
return self.__send(self.__name, args)
File "C:\Python27\lib\xmlrpclib.py", line 1575, in __request
verbose=self.__verbose
File "C:\Python27\lib\xmlrpclib.py", line 1264, in request
return self.single_request(host, handler, request_body, verbose)
File "C:\Python27\lib\xmlrpclib.py", line 1289, in single_request
self.send_request(h, handler, request_body)
File "C:\Python27\lib\xmlrpclib.py", line 1391, in send_request
connection.putrequest("POST", handler, skip_accept_encoding=True)
File "C:\Python27\lib\httplib.py", line 853, in putrequest
raise CannotSendRequest()
httplib.CannotSendRequest
Traceback (most recent call last):
File "H:\poker\repos\TestSuite\test.py", line 46, in run
print self.mm.one()
File "C:\Python27\lib\xmlrpclib.py", line 1224, in __call__
return self.__send(self.__name, args)
File "C:\Python27\lib\xmlrpclib.py", line 1575, in __request
verbose=self.__verbose
File "C:\Python27\lib\xmlrpclib.py", line 1264, in request
return self.single_request(host, handler, request_body, verbose)
File "C:\Python27\lib\xmlrpclib.py", line 1294, in single_request
response = h.getresponse(buffering=True)
File "C:\Python27\lib\httplib.py", line 1015, in getresponse
raise ResponseNotReady()
httplib.ResponseNotReady
.
하나의 스레드 만 사용할 때는
$ 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
.
두 개의 다른 인스턴스를 사용할 때도 잘 작동합니다.
$ 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
. 해결책
코드와 함께 보았던 몇 가지 문제가 있었지만, 주로 내가 곧바로 얻은 것은 서버가 준비되기 전에 클라이언트를 시작했다는 것입니다. 서버를 먼저 인스턴스화했을 때 클라이언트가 연결 오류가 발생하지 않았습니다.
나는 또한 루프 동안 회전을 제거하고 대신 PYQT 이벤트 루프를 시작했습니다. 또한 귀하가 귀하의 요청 수업에 귀하의 MM 인스턴스를 통과하는 데 묻는 것이 좋습니다 (동일한 인스턴스를 사용하고 있으므로이 예제에 대해 중요하지 않음).
어쨌든, 여기에있는 것처럼 보이는 버전은 다음과 같습니다.
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(.25)
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()
.
업데이트
이 조금 더 많이 찾은 후 파이썬 2.7과 XMLRPC의 버그가 연결을 만드는 방법을 변경했습니다. http://bugs.python.org/issue6907
이상하게이 코드는 OSX에서 파이썬 2.6 / 2.7 또는 Linux에서 파이썬 2.6에서 나를 충돌시키지 않습니다. 그러나 그것은 Linux에서 파이썬 2.7에서 저를 위해 추락합니다.
MM 인스턴스 외부의 잠금 메커니즘을 이동하면 Linux에서 2.7 미만으로 작동하는 것처럼 보였습니다.
class MM(object):
def __init__(self):
self.xmlrpc_client = xmlrpclib.ServerProxy('http://localhost:9093')
def __getattr__(self, name):
return self.xmlrpc_client.__getattr__(name)
class Ask(QtCore.QThread):
def __init__(self, mmInst, lock):
QtCore.QThread.__init__(self)
self.mm = mmInst
self.lock = lock
def run(self):
while not self._stopping:
time.sleep(0.5)
self.lock.lock()
print self.mm.one()
self.lock.unlock()
def start_gui():
app = QtGui.QApplication(sys.argv)
...
lock = QtCore.QMutex()
a1 = Ask(mm, lock)
a1.start()
a2 = Ask(mm, lock)
a2.start()
. 제휴하지 않습니다 StackOverflow