我目前正在使用一个带有多个线程的Python 2.7脚本。其中一个线程在长轮询模式下侦听JSON数据,并在接收或在一段时间后进入超时后解析它。我注意到它只在调试模式下工作(我使用Wing IDE)。在正常运行的情况下,在进入" for"之前,看起来这个脚本的特定线程在第一次GET请求之后挂起。环。循环条件不会影响结果。与此同时,其他线程继续正常工作。
我认为这与多线程有关。如何正确排除故障并解决此问题?
下面我把类的代码负责长轮询工作。
class Listener(threading.Thread):
def __init__(self, router, *args, **kwargs):
self.stop = False
self._cid = kwargs.pop("cid", None)
self._auth = kwargs.pop("auth", None)
self._router = router
self._c = webclient.AAHWebClient()
threading.Thread.__init__(self, *args, **kwargs)
def run(self):
while True:
try:
# Data items that should be routed to the device is retrieved by doing a
# long polling GET request on the "/tunnel" resource. This will block until
# there are data items available, or the request times out
log.info("LISTENER: Waiting for data...")
response = self._c.send_request("GET", self._cid, auth=self._auth)
# A timed out request will not contain any data
if len(response) == 0:
log.info("LISTENER: No data this time")
else:
items = response["resources"]["tunnel"]
undeliverable = []
#print items # - reaching this point, able to return output
for item in items:
# The data items contains the data as a base64 encoded string and the
# external reference ID for the device that should receive it
extId = item["extId"]
data = base64.b64decode(item["data"])
# Try to deliver the data to the device identified by "extId"
if not self._router.route(extId, data):
item["message"] = "Could not be routed"
undeliverable.append(item)
# Data items that for some reason could not be delivered to the device should
# be POST:ed back to the "/tunnel" resource as "undeliverable"
if len(undeliverable) > 0:
log.warning("LISTENER: Sending error report...")
response = self._c.send_request("POST", "/tunnel", body={"undeliverable": undeliverable}, auth=self._auth)
except webclient.RequestError as e:
log.error("LISTENER: ERROR %d - %s", e.status, e.response)
UPD:
class Router:
def route(self, extId, data):
log.info("ROUTER: Received data for %s: %s", extId, repr(data))
# nothing special
return True
答案 0 :(得分:0)
如果您正在使用CPython解释器you're not actually system threading:
CPython实现细节:在CPython中,由于Global 解释器锁,只有一个线程可以一次执行Python代码 (即使某些面向性能的库可能会克服 这个限制)。如果您希望您的应用程序更好地使用 建议您使用多核机器的计算资源 使用多处理。但是,线程仍然是一个合适的模型 如果你想同时运行多个I / O绑定任务。
因此,在收听第一个请求时,您的进程可能会锁定,因为您需要长时间轮询。
多处理可能是更好的选择。我没有尝试过长时间轮询,但the Twisted framework也可能适用于您的情况。