如下使用tonado遇到问题,当一个服务调用自身时,会发生线程的阻塞
#coding=utf-8
import tornado.web
import tornado.gen
import tornado.httpclient
import tornado
import threading
thread_num = 10
class Application(tornado.web.Application):
def __init__(self):
handlers = [(r'/handler1/(.*)/(.*)', Handler1),
(r'/handler2', Handler2),]
tornado.web.Application.__init__(self,handlers)
class Handler2(tornado.web.RequestHandler):
@tornado.web.asynchronous
@tornado.gen.engine
def get(self, *args):
# 浏览器输入url : http://127.0.0.1:8888/handler1/aaa/bbb
print 'in handler2 get...........'
self.write('handler2 response')
self.finish()
class Handler1(tornado.web.RequestHandler):
@tornado.web.asynchronous
@tornado.gen.engine
def get(self, *args):
# 浏览器输入url : http://127.0.0.1:8888/handler1/aaa/bbb
self.thread_lock = threading.Lock()
response = yield tornado.gen.Task(self.method)
self.write(str(response))
print 'after self.write....'
self.finish()
@tornado.gen.engine
def method(self, callback):
self.response = []
threads = []
for i in range(thread_num):
thr = threading.Thread(target=self.fun, args=(i, callback))
threads.append(thr)
for t in threads:
t.start()
for t in threads:
t.join()
print 'after join, ......... %s' % threads
yield tornado.gen.Task(self.wait_response)
callback(self.response)
@tornado.gen.engine
def wait_response(self, callback):
while len(self.response) < 10:
continue
callback(None)
@tornado.web.asynchronous
@tornado.gen.engine
def fun(self, i, calback):
import urllib2, time
print 'aaaaaaaaaaa'
# response = urllib2.urlopen("http://127.0.0.1:8888/handler1/aaa/bbb")
http_client = tornado.httpclient.AsyncHTTPClient()
response = yield tornado.gen.Task(http_client.fetch, "http://127.0.0.1:8888/handler2")
print time.time(), response
with self.thread_lock:
self.response.append('xxx: ' + str(i))
if __name__=='__main__':
application = Application()
application.listen(8888)
# application.listen(8889)
tornado.ioloop.IOLoop.instance().start()
使用tornado4的协程解决该问题:
#coding=utf-8
import tornado.web
import tornado.gen
import tornado.httpclient
import tornado
from tornado import gen
import threading
thread_num = 10
class Application(tornado.web.Application):
def __init__(self):
handlers = [(r'/handler1/(.*)/(.*)', Handler1),
(r'/handler2', Handler2),]
tornado.web.Application.__init__(self,handlers)
class Handler2(tornado.web.RequestHandler):
@gen.coroutine
def get(self, *args):
# 浏览器输入url : http://127.0.0.1:8888/handler1/aaa/bbb
print 'in handler2 get...........'
self.write('handler2 response')
self.finish()
class Handler1(tornado.web.RequestHandler):
@gen.coroutine
def get(self, *args):
# 浏览器输入url : http://127.0.0.1:8888/handler1/aaa/bbb
self.thread_lock = threading.Lock()
response = yield self.method()
self.write(str(response))
print 'after self.write....'
self.finish()
@gen.coroutine
def method(self,):
self.response = []
# threads = []
# for i in range(thread_num):
# thr = threading.Thread(target=self.fun, args=(i,))
# threads.append(thr)
# for t in threads:
# t.start()
# for t in threads:
# t.join()
# print 'after join, ......... %s' % threads
# yield tornado.gen.Task(self.wait_response)
for i in range(thread_num):
yield self.fun(i)
raise gen.Return(self.response)
@gen.coroutine
def fun(self, i):
import urllib2, time
print 'aaaaaaaaaaa'
# response = urllib2.urlopen("http://127.0.0.1:8888/handler1/aaa/bbb")
http_client = tornado.httpclient.AsyncHTTPClient()
response = yield http_client.fetch("http://127.0.0.1:8888/handler2")
print time.time(), response
with self.thread_lock:
self.response.append('xxx: ' + str(i))
# callback(None)
if __name__=='__main__':
application = Application()
application.listen(8888)
# application.listen(8889)
tornado.ioloop.IOLoop.instance().start()