gpt4 book ai didi

python - QThreads 和 xmlrpc 客户端

转载 作者:行者123 更新时间:2023-12-01 06:02:22 25 4
gpt4 key购买 nike

我正在尝试使用来自许多 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()

但是它不起作用,我不知道为什么。这是输出:

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

当使用两个不同的 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

最佳答案

我在代码中发现了一些问题,但主要是我立即遇到的问题是您在服务器准备就绪之前启动了客户端。当我首先实例化服务器,然后实例化客户端时,我不再收到连接错误。

我还删除了旋转的 while 循环,而只是启动了 pyqt 事件循环。另外,您并没有真正将 MM 实例传递给 Ask 类(这对于本示例来说并不重要,因为您使用的是相同的实例)。

无论如何,这是我的版本,似乎可以正常工作:

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()

更新

经过更多研究后,我意识到这是 python 2.7 和 xmlrpc 中的一个错误,它们改变了创建连接的方式。 http://bugs.python.org/issue6907

奇怪的是,这段代码在 OSX 上的 python 2.6/2.7 上或在 linux 下的 python 2.6 上不会崩溃。但对于我来说,在 linux 下使用 python 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()

关于python - QThreads 和 xmlrpc 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9691938/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com