方式一:通过线程池或者进程池
导入库futures是python3自带的库,如果是python2,需要pip安装future这个库
备注:进程池和线程池写法相同
 1 from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
 2 from tornado.concurrent import run_on_executor
 3
 4 def doing(s):
 5     print('xiumian--{}'.format(s))
 6     time.sleep(s)
 7     return s
 8
 9 class MyMainHandler(RequestHandler):
10     executor = ProcessPoolExecutor(2)   #新建一个进程池,静态变量,属于类,所以全程只有这个几个进程,不需要关闭,如果放在__init__中,则属于对象,每次请求都会新建pool,当请求增多的时候,会导致今天变得非常多,这个方法不可取
11
12     @gen.coroutine
13     def get(self, *args, **kwargs):
14         print('开始{}'.format(self.pool_temp))
15         a = yield self.executor.submit(doing, 20)
16         print('进程 %s'  % self.executor._processes)
17         self.write(str(a))
18         print('执行完毕{}'.format(a))
19
20    @run_on_executor       #tornado 另外一种写法,需要在静态变量中有executor的进程池变量
21     def post(self, *args, **kwargs):
22 a = yield doing(20)

方式二:Tornado + Celery + RabbitMQ 实现
使用Celery任务队列,Celery 只是一个任务队列,需要一个broker媒介,将耗时的任务传递给Celery任务队列执行,执行完毕将结果通过broker媒介返回。官方推荐使用RabbitMQ作为消息传递,redis也可以
一、Celery 介绍:
1.1、注意:
1、当使用RabbitMQ时,需要按照pika第三方库,pika0.10.0存在bug,无法获得回调信息,需要按照0.9.14版本即可
2、tornado-celery 库比较旧,无法适应Celery的最新版,会导致报无法导入task Producter包错误,只需要将celery版本按照在3.0.25就可以了
1.2、关于配置:
单个参数配置:
1 app.conf.CELERY_RESULT_BACKEND = 'redis://localhost:6379/0' 
多个参数配置:
1 app.conf.update(
2     CELERY_BROKER_URL = 'amqp://guest@localhost//',
3     CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
4 )

从配置文件中获取:(将配置参数写在文件app.py中)
1 BROKER_URL='amqp://guest@localhost//'
2 CELERY_RESULT_BACKEND='redis://localhost:6379/0'
3 app.config_from_object('celeryconfig')

二、案例
2.1、启动一个Celery 任务队列,也就是消费者:
1 from celery import Celery
2 celery = Celery('tasks', broker='amqp://guest:guest@119.29.151.45:5672', backend='amqp')  使用RabbitMQ作为载体, 回调也是使用rabbit作为载体
3
4 @celery.task(name='doing')   #异步任务,需要命一个独一无二的名字
5 def doing(s, b):
6     print('开始任务')
7     logging.warning('开始任务--{}'.format(s))
8     time.sleep(s)
9     return s+b

命令行启动任务队列守护进程,当队列中有任务时,自动执行 (命令行可以放在supervisor中管理)
--loglevel=info --concurrency=5
记录等级,默认是concurrency:指定工作进程数量,默认是CPU核心数
2.2、启动任务生产者

 1 import tcelery
 2 tcelery.setup_nonblocking_producer()  #设置为非阻塞生产者,否则无法获取回调信息
 3
 4 class MyMainHandler(RequestHandler):
 5
 6     @web.asynchronous
 7     @gen.coroutine
 8     def get(self, *args, **kwargs):
 9         print('begin')
10         result = yield gen.Task(sleep.apply_async, args=[10])   #使用yield 获取异步返回值,会一直等待但是不阻塞其他请求
11         print('ok--{}'.format(result.result))     #返回值结果
12
13        # sleep.apply_async((10, ), callback=self.on_success)
14        # print('ok -- {}'.format(result.get(timeout=100)))#使用回调的方式获取返回值,发送任务之后,请求结束,所以不能放在处理tornado的请求任务当中,因为请求已经结束了,与客户端已经断开连接,无法再在获取返回值的回调中继续向客户端返回数据
15
16         # result = sleep.delay(10)    #delay方法只是对apply_async方法的封装而已
17         # data = result.get(timeout=100)  #使用get方法获取返回值,会导致阻塞,相当于同步执行
18
19
20     def on_success(self, response):    #回调函数
21         print ('Ok-- {}'.format(response))

转载于:https://www.cnblogs.com/hepingqingfeng/p/6655790.html

Tornado 高并发源码分析之六---异步编程的几种实现方式相关推荐

  1. 聊聊异步编程的 7 种实现方式

    大家好,我是 Tom哥 最近有很多小伙伴给我留言,能不能总结下异步编程,今天就和大家简单聊聊这个话题. 早期的系统是同步的,容易理解,我们来看个例子 同步编程 当用户创建一笔电商交易订单时,要经历的业 ...

  2. 【Android 事件分发】ItemTouchHelper 事件分发源码分析 ( 绑定 RecyclerView )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  3. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  4. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 六 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  5. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  6. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  7. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 三 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  8. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 二 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  9. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 一 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

最新文章

  1. Jürgen Schmidhuber发文纪念10年前的研究,网友:转折点非AlexNet?
  2. Interview with BOA
  3. Java生成随机数的几种高级用法
  4. oracle查看数据库是否恢复成功_记一次解决docker下oracle数据库故障事例
  5. Ajax 调用webservice 解决跨域请求和发布到服务器后本地调用成功外网失败的问题...
  6. 文件服务器serv-u,Serv-U文件服务器.PDF
  7. XHML教会我的一些东西-5
  8. tp6 使用workerman
  9. 打字测试软件源码 vb,打字测试程序 VB代码
  10. android组合按键截屏,如果你的安卓手机支持〔电源〕键+〔音量减〕键截屏,你可以代码...
  11. java 按钮添加音乐_如何使得java swing里加入的背景音乐 可用按钮控制播放与停止...
  12. [UML]建模是什么?为什么要建模?
  13. 第4章【思考与练习2】数据文件high-speed rail.csv存放着世界各国高速铁路的情况。对世界各国高铁的数据进行绘图分析。使用Basemap绘制地图及使用Pyecharts绘制地图。
  14. 话题中的Publisher和Subscriber
  15. textarea 中的换行、空格; 如何处理
  16. python-对水平和垂直投影图做曲线拟合
  17. 信托资金将分辨用于向邢台依林山庄食物有限公司、唐山国泰纸业有限公司、唐山蓝猫饮品团体有限公司发放流动资金贷款1亿、1.5亿、1亿
  18. java基础学习总结(二)——开篇(转载于孤傲苍狼博主的心得体会)
  19. 刻录原版系统光盘(用软碟通)
  20. 太极计算机工程与应用,论“大恒”、“太极”、“太极图”

热门文章

  1. phpStrom编辑器常用功能教程
  2. golang select default continue_golang系列——基础语法
  3. KICAD | 分享一个必须安装的插件Interactive HTML BOM plugin for KiCad
  4. Keil | 解决Keil双击工程名无法打开.map的问题
  5. java conterller_java后台controller能否直接接收list
  6. colorpix取色小工具_五款互联网人必备的免费工具,超级实用
  7. win7磁盘清理_为什么要清理磁盘碎片,win7电脑怎么清理磁盘碎片
  8. C++工作笔记-对继承的进一步认识
  9. mysql导入_导出命令_MySQL导入导出命令
  10. 周期均方根和有效值的区别_买羊肉,“羔羊肉”和“羊肉”有啥区别?口感差别大,别再乱买了...