该脚本的性能如何:http://tornadogists.org/2185380/ http://tornadogists.org/2185380/复制如下。
from time import sleep
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.web import Application, asynchronous, RequestHandler
from multiprocessing.pool import ThreadPool
_workers = ThreadPool(10)
def run_background(func, callback, args=(), kwds={}):
def _callback(result):
IOLoop.instance().add_callback(lambda: callback(result))
_workers.apply_async(func, args, kwds, _callback)
# blocking task like querying to MySQL
def blocking_task(n):
sleep(n)
return n
class Handler(RequestHandler):
@asynchronous
def get(self):
run_background(blocking_task, self.on_complete, (10,))
def on_complete(self, res):
self.write("Test {0}<br/>".format(res))
self.finish()
HTTPServer(Application([("/", Handler)],debug=True)).listen(8888)
IOLoop.instance().start()
- 我的申请将会结束1,000 请求/秒.
- Each request will last from 2-30 seconds, averaging about 6 seconds
- 通过使用类似的方法来阻止 IO
redis BLPOP
or Queue.get_nowait()
总体模式很好,但需要注意的是,由于 GIL,您的线程池将只能使用单个 CPU,并且您需要使用多个进程来充分利用可用的硬件。
仔细看看这些数字,如果您的请求确实平均每个请求需要 6 秒,那么 10 个线程就太小了。每秒都有 6000 秒的工作量,因此您的所有进程总共需要至少 6000 个线程(假设这 6 秒实际上只是阻塞外部事件以及 python 进程中的 CPU 成本)是可以忽略不计的)。我不确定现代系统可以处理多少个线程,但 6000 个 Python 线程听起来并不是一个好主意。如果每个请求确实有 6 秒的阻塞(以及每秒数千个请求),那么将这些阻塞函数转换为异步函数似乎是值得的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)