所以我在我的类
中创建了一个名为executor的类变量executor = ThreadPoolExecutor(100)
而不是使用函数和方法并使用装饰器,我只是使用以下行来处理我的异步方法中的阻塞任务(如io和哈希创建和......)
result = await to_tornado_future(self.executor.submit(blocking_method, param1, param2)
我决定使用这种风格的原因
1-装饰者性质较慢
2-不需要额外的方法和功能
3-它按预期工作,并在需要之前不创建线程
我是对的吗?请使用原因(我想知道我使用的方式,更慢或使用更多资源或....)
更新
根据Ben的回答,我的上述方法不正确 所以我最终根据需要使用了以下功能,我认为这是最好的方式
def pool(pool_executor, fn, *args, **kwargs):
new_future = Future()
result_future = pool_executor.submit(fn, *args, **kwargs)
result_future.add_done_callback(lambda f: new_future.set_result(f.result()))
return new_future
用法:
result = await pool(self.executor, time.sleep, 3)
答案 0 :(得分:5)
只要所有阻塞方法都是线程安全的,这是安全的。既然你提到在这些线程中做IO,我会指出在这里做文件IO很好但是Tornado中的所有网络IO都必须在IOLoop的线程上发生。
为什么你说“装饰者性质较慢”?哪个装饰器比什么慢?一些装饰器根本没有性能开销(尽管大多数都有一些运行时成本)。 to_tornado_future(executor.submit())
也不是免费的。 (顺便说一句,我想你想要tornado.gen.convert_yielded
而不是tornado.platform.asyncio.to_tornado_future
。executor.submit
不会返回asyncio.Future
。)
作为一般规则,在线程池上运行blocking_method
将比直接调用更慢。只有在blocking_method
可能阻塞足够长的时间以至于您希望主线程在此期间可以自由地执行其他操作时,才应执行此操作。