python 单线程和异步协程工作方式解析


Posted in Python onSeptember 28, 2019

在python3.4之后新增了asyncio模块,可以帮我们检测IO(只能是网络IO【HTTP连接就是网络IO操作】),实现应用程序级别的切换(异步IO)。注意:asyncio只能发tcp级别的请求,不能发http协议。

 异步IO:所谓「异步 IO」,就是你发起一个 网络IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知。

实现方式:单线程+协程实现异步IO操作。

异步协程用法

接下来让我们来了解下协程的实现,从 Python 3.4 开始,Python 中加入了协程的概念,但这个版本的协程还是以生成器对象为基础的,在 Python 3.5 则增加了 async/await,使得协程的实现更加方便。首先我们需要了解下面几个概念:

  • event_loop:事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上,当满足条件发生的时候,就会调用对应的处理方法。
  • coroutine:中文翻译叫协程,在 Python 中常指代为协程对象类型,我们可以将协程对象注册到时间循环中,它会被事件循环调用。我们可以使用 async 关键字来定义一个方法,这个方法在调用时不会立即被执行,而是返回一个协程对象。
  • task:任务,它是对协程对象的进一步封装,包含了任务的各个状态。
  • future:代表将来执行或没有执行的任务的结果,实际上和 task 没有本质区别。

另外我们还需要了解 async/await 关键字,它是从 Python 3.5 才出现的,专门用于定义协程。其中,async 定义一个协程,await 用来挂起阻塞方法的执行。

1.定义一个协程

示例:

from time import sleep
import asyncio

async def request(url):
  print('正在请求url')
  sleep(2)
  print('下载成功')

# 返回一个特殊的协程对象,request函数内部不会被执行
c = request('www.baidu.com')

# 实例化一个事件循环对象
loop = asyncio.get_event_loop()

# 基于事件循环对象创建一个任务对象,并将协程对象封装到该对象中
task = loop.create_task(c)

# 另一种形式实例化任务对象的方法
task = asyncio.ensure_future(c)

# 将协程对象注册到事件循环对象中,并需要启动事件循环对象
# 当事件循环对象内的第一个参数遇到阻塞是,就会自动执行后面的对象,当第一个对象的阻塞结束是会上报给事件循环对象,然后事件循环对象继续执行第一个对象,从而达到异步的效果
loop.run_until_complete(task)

2.给任务对象绑定回调

import asyncio

async def request(url):
  print('正在请求url')
  print('下载成功')
  return url

# 回调函数必须有一个参数:task【任务对象】
# task.result():任务对象中封装的协程对象对应的特殊函数内部的返回值
def callback(task):
  print('this is callback')
  print(task.result())

c = request('www.baidu.com')
# 创建一个任务对象
task = asyncio.ensure_future(c)
# 给任务对象绑定一个回调函数
task.add_done_callback(callback)
# 实例化一个事件循环对象
loop = asyncio.get_event_loop()
# 将协程对象注册到事件循环对象中,并需要启动事件循环对象
loop.run_until_complete(task)

3.多任务异步协程

import asyncio
import time

urls = ['www.baidu.com','www.sogou,com','www.goubanjia.com']
start_time = time.time()
async def request(url):
  print('正在请求url')
  # 在多任务异步协程事项中,不可以出现不支持异步的相关代码,sleep不支持
  # sleep(2)
  await asyncio.sleep(2)
  print('下载成功')

loop = asyncio.get_event_loop()
# 任务列表:防止多个任务对象
tasks = []
for url in urls:
  c = request(url)
  task = asyncio.ensure_future(c)
  tasks.append(task)

loop.run_until_complete(asyncio.wait(tasks))
print(time.time() - start_time)

4.多异步任务协程应用

# aiohttp:支持异步的一个基于网络请求的模块
import aiohttp
import asyncio
import time

urls = ['http://127.0.0.1:5000/jay',
    'http://127.0.0.1:5000/bobo',
    'http://127.0.0.1:5000/tom',]

start_time = time.time()

async def get_pageText(url):
  async with aiohttp.ClientSession() as s:# 实例化请求对象
    async with await s.get(url) as response:
      page_text = await response.text()
      print(page_text)
      # 这里有返回值,是因为要用回调函数进行数据解析
      return page_text

# 封装回调函数用于数据解析
def parse(task):
  # 1.获取相应数据
  page_text = task.reault()
  print(page_text+',即将进行数据解析...')
  # 以下解析操作


tasks = []
for url in urls:
  c = get_pageText(url)
  task = asyncio.ensure_future(c)
  # 给任务对象绑定回调函数用于数据解析
  task.add_done_callback(parse)
  tasks.append(task)

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
print(time.time() - start_time)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
linux系统使用python获取cpu信息脚本分享
Jan 15 Python
python中list列表的高级函数
May 17 Python
python构建深度神经网络(续)
Mar 10 Python
Python import与from import使用及区别介绍
Sep 06 Python
python使用xlsxwriter实现有向无环图到Excel的转换
Dec 12 Python
python定时复制远程文件夹中所有文件
Apr 30 Python
Django框架验证码用法实例分析
May 10 Python
python将excel转换为csv的代码方法总结
Jul 03 Python
Jupyter Notebook打开任意文件夹操作
Apr 14 Python
python工具快速为音视频自动生成字幕(使用说明)
Jan 27 Python
Python tkinter之ComboBox(下拉框)的使用简介
Feb 05 Python
浅谈Python实现opencv之图片色素的数值运算和逻辑运算
Jun 23 Python
python爬虫 正则表达式解析
Sep 28 #Python
python爬虫 Pyppeteer使用方法解析
Sep 28 #Python
python安装scipy的步骤解析
Sep 28 #Python
python网络爬虫 CrawlSpider使用详解
Sep 27 #Python
python numpy存取文件的方式
Apr 01 #Python
100行Python代码实现每天不同时间段定时给女友发消息
Sep 27 #Python
使用Fabric自动化部署Django项目的实现
Sep 27 #Python
You might like
德生S2000收音机更换“钕铁硼”全频扬声器
2021/03/02 无线电
PHP分页显示制作详细讲解
2008/11/19 PHP
2个自定义的PHP in_array 函数,解决大量数据判断in_array的效率问题
2014/04/08 PHP
PHP对象、模式与实践之高级特性分析
2016/12/08 PHP
PHP基于正则批量替换Img中src内容实现获取缩略图的功能示例
2017/06/07 PHP
JavaScript基本对象
2007/01/11 Javascript
用javascript自动显示最后更新时间
2007/03/15 Javascript
PPK 谈 JavaScript 的 this 关键字 [翻译]
2009/09/29 Javascript
基于JQuery的动态删除Table表格的行和列的代码
2011/05/12 Javascript
邮箱下拉自动填充选择示例代码附图
2014/04/03 Javascript
javascript中scrollTop详解
2015/04/13 Javascript
自制微信公众号一键排版工具
2016/09/22 Javascript
jstree创建无限分级树的方法【基于ajax动态创建子节点】
2016/10/25 Javascript
在百度搜索结果中去除掉一些网站的资料(通过js控制不让显示)
2017/05/02 Javascript
jQuery UI Draggable + Sortable 结合使用(实例讲解)
2017/09/07 jQuery
JS实现十分钟倒计时代码实例
2018/10/18 Javascript
webpack4+express+mongodb+vue实现增删改查的示例
2018/11/08 Javascript
jquery3和layui冲突导致使用layui.layer.full弹出全屏iframe窗口时高度152px问题
2019/05/12 jQuery
原生JS实现顶部导航栏显示按钮+搜索框功能
2019/12/25 Javascript
[01:00:10]完美世界DOTA2联赛PWL S2 FTD vs Inki 第二场 11.21
2020/11/24 DOTA
python中pandas.DataFrame排除特定行方法示例
2017/03/12 Python
python生成二维码的实例详解
2017/10/29 Python
名片管理系统python版
2018/01/11 Python
python 读取.csv文件数据到数组(矩阵)的实例讲解
2018/06/14 Python
python实现在图片上画特定大小角度矩形框
2018/10/24 Python
django如何自己创建一个中间件
2019/07/24 Python
介绍CSS3使用技巧5个
2009/04/02 HTML / CSS
波兰品牌鞋履在线商店:Eastend.pl
2020/01/11 全球购物
大学毕业感言50字
2014/02/07 职场文书
勾股定理课后反思
2014/04/26 职场文书
文明寝室申报材料
2014/05/12 职场文书
党委书记个人对照检查材料
2014/09/15 职场文书
领导班子党的群众路线对照检查材料
2014/09/25 职场文书
2014年敬老院工作总结
2014/12/08 职场文书
安全员岗位职责
2015/02/10 职场文书
2016年教师反腐倡廉心得体会
2016/01/13 职场文书