01 同步和异步

生活中常常会遇到在超市排队买东西的情况,排在你前面的人没有结算完成,你就无法付账,在计算机中也有类似的情形,一个程序在执行之前,需要等待其他的程序执行完成,大家还能举出其他的例子吗?

同步

含义:指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系

现象:有一个共同的时钟,按来的顺序一个一个处理

直观感受 :就是需要等候,效率低下

异步

含义 :双方不需要共同的时钟,也就是接收方不知道发送方什么时候发送,所以在发送的信息中就要有提示接收方开始接收的信息,如开始位,同时在结束时有停止位

现象:没有共同的时钟,不考虑顺序来了就处理

直观感受:就是不用等了,效率高

02 阻塞和非阻塞

同样是刚才排队的情形,当你在排队的同时,你的状态是怎样的呢?在计算机里面应该怎么描述呢?

阻塞调用与非阻塞调用

阻塞调用

含义 : 阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,CPU不会给线程分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回

现象:读套接字时没有数据等数据来,写套接字时写不下了也一直等,等能写下了往里写(套接字被写满的原因不在本地,在于网络另一头的套接字被写满了来不及读出去,导致本地的套接字内容来发不出去堵住了)

直观感受:执着

非阻塞调用

含义 :非阻塞调用是指没有调用结果立即返回,当前线程不被挂起,可以继续做其它工作

现象:读套接字时没有数据,不等直接返回干别的事去,写套接字写不下了也不写了,直接返回干别的事去

直观感受:勤奋

03 异步编程

三种方式:协程,回调函数,requests

在前面的介绍的基础上,来看下 Tornado 中,当同时有多个请求发送过来时,而且其中还有请求发生阻塞,会产生什么样的后果呢?

通过回调函数来实现异步

import tornado.httpclient

class CallbackHandler(BaseHandler): """通过回调函数来实现异步"""

   @tornado.web.asynchronous

   def get(self):

     client = tornado.httpclient.AsyncHTTPClient() # 异步的方

    client.fetch("http://127.0.0.1:8000/sync",callback=self.on_response) self.write('Ok!'+' ')

  def on_response(self,response): ​

     self.write(response.body) ​

     self.finish() # 注意一定要加上,回调的异步完成后不会自动执行finish,所以在这里要手动加上.

通过协程实现异步

导入模块

import tornado.gen

class GenHandler(BaseHandler): """通过协程实现的异步"""

   @tornado.web.asynchronous

   @tornado.gen.coroutine # coroutine 协程

  def get(self): ​

  client = tornado.httpclient.AsyncHTTPClient() ​

  response = yield tornado.gen.Task(client.fetch,"http://127.0.0.1:8000/sync") ​

  self.write(response.body)

通过协程实现异步(自定义函数)

class FuncHandler(BaseHandler): """通过协程实现的异步"""

   @tornado.web.asynchronous

   @tornado.gen.coroutine # coroutine 协程

   def get(self):

   response = yield self.func()

   print(response)

   self.write(response.body)

   @tornado.gen.coroutine

   def func(self):

     client = tornado.httpclient.AsyncHTTPClient()

     response = yield tornado.gen.Task(client.fetch,"http://127.0.0.1:8000/sync")

     raise tornado.gen.Return(response)

通过协程来实现异步(使用requests模块)

第一步:安装模块

pip install futures

pip install requests

第二步:导入模块

from tornado.concurrent import run_on_executor

from concurrent.futures import ThreadPoolExecutor

import requests

通过协程来实现异步(使用requests模块)

class MyFuncHandler(BaseHandler): """通过协程实现的异步"""

   executor = ThreadPoolExecutor()

   @tornado.web.asynchronous

   @tornado.gen.coroutine # coroutine 协程

   def get(self):

     response = yield self.func()

     print(response)

     self.write(response.text)

   @run_on_executor

   def func(self):

   response = requests.get("http://127.0.0.1:8000/sync")

   return response

tornado框架基础11-tornado异步的更多相关文章

  1. tornado框架基础10-websocket

    websocket 01 长轮询 在网页,我们经常扫码登录,结合之前的学习的知识点,来思考下,前端是如何知道用户在手机上扫码登录了呢? 长轮询:客户端不断的向服务器发送请求 缺点: \1. 开销大 \ ...

  2. tornado框架基础01-路由简介

    tornado 小而精 Django 大而全 Web框架 Tornado是一个由Python开发的Web框架 Web服务 利用Tornado,可以快速搭建和一个高性能的Web服务 非阻塞 Tornad ...

  3. tornado框架基础09-cookie和session

    01 cookie 在上节,我们简单了解了登录过程,但是很明显,每次都需要登录,但是在平常逛网站的只需要登录一次,那么网站是如何记录登录信息的呢? 有没有什么办法可以让浏览器记住登录信息,下次再次打开 ...

  4. tornado框架基础08-sqlalchemy表关系和简单登录注册

    01 一对一表关系 Module 需要先创建对应的 Module ,这里采用之前建立好的 User 和 UserDetails relationship from sqlalchemy.orm imp ...

  5. tornado框架基础05-模板继承、UImodul和UImethods

    01 模板继承 父模板​ <html lang="en"> <head>     <meta charset="UTF-8"> ...

  6. tornado框架基础04-模板基础

    01 模板 模板演示 配置路径 在 application 中配置模板文件和静态文件的路径: template_path='templates', static_path='static', 模板 & ...

  7. tornado框架基础03-请求与响应

    01 请求与响应 请求 浏览器在发送请求的时候,会发送具体的请求信息,由请求行,请求消息头,请求正文 请求消息头 向服务器传递附加信息 Accept: 浏览器可以接受的MIME类型. Accept-C ...

  8. tornado框架基础02-输入和输出

    01 输出 write bytes类型 class IndexHandler(tornado.web.RequestHandler): def get(self): self.write(b'Torn ...

  9. tornado框架基础06-SQLAlchemy连接数据库

    01 ORM 在服务器后台,数据是要存储在数据库的,但是如果项目在开发和部署的时候,是使用的不同的数据库,该怎么办呢?是不是需要把所有的 SQL 语句都再重新写一遍呢? 和数据库相关,不同的数据库需要 ...

随机推荐

  1. Oracle 单引号与双引号的区别

    双引号一般是用来转义的,如果alias里面有空格或其它保留符号,必须使用双引号.而单引号是用来特制的,比如字符串的引用,日期字符串的引用,都必须包括在单引号中,可以参与运算或其它表达式中.两者不可混用 ...

  2. windows clone 迁移数据库

    windows clone 迁移数据库可行.(c 盘底成复制)

  3. B. Connecting Universities DFS,无向树

    http://codeforces.com/problemset/problem/700/B 题意是,在一颗树中,有k个大学,要求两两匹配,他们之间的距离作为贡献,使得距离总和最大. 一开始的时候无从 ...

  4. solr 包地址

    http://archive.apache.org/dist/lucene/solr/6.3.0/

  5. Bootstrap中的datetimepicker浅谈

    从古至今,人们都习惯用某个时间来标记某个事件的发生.我们在写管理后台的时候,重中之中也是这个时间的设置.在问题出现的时候,我们是查看日志的时候,就可以根据这个时间段来查找这个问题出现点. 在使用时间控 ...

  6. AJPFX总结String类的特点

          String str = "abc"; str就是String的一个对象         字符串一旦被赋值, 值就不能再被改变了         举例:String s ...

  7. SpringBoot 2.x (7):拦截器

    类似以前SpringMVC的拦截器,但也有一些区别 SpringBoot的拦截器有两种方式: 第一种方式:过时的方式,适用于SpringBoot1.x的方式 package org.dreamtech ...

  8. iphone x 高度:100%; 兼容设置

    问题: iphone x 会遇到页面设置 height:100%;之后但是底部还有一定的高度没有覆盖 解决方法: 1.让客户端设置webview的高度为100%; 2.html代码里面添加 viewp ...

  9. Ajax深入理解

    Ajax  Asynchronous JavaScript and XML 异步的JavaScript和XML ajax通过与后台服务器进行少量的数据交换,ajax可以使页面实现异步更新,即不需要重新 ...

  10. ceph集群一键部署脚本

    分布式存储ceph相信大家比较熟悉了.某项目临时要做一个40个节点的存储集群.所以写了这个脚本. 一键部署脚本如下: git clone https://github.com/luckman666/d ...