13.1 事件循环

asyncio
包含各种特定系统实现的模块化事件循环
传输和协议抽象
对TCP、UDP、SSL、子进程、延时调用以及其他的具体支持
模仿futures模块但适用于事件循环使用的Future类
基于 yield from 的协议和任务,可以让你用顺序的方式编写并发代码
必须使用一个将产生阻塞IO的调用时,有接口可以把这个事件转移到线程池
模仿threading模块中的同步原语、可以用在单线程内的协程之间

事件循环+回调(驱动生成器)+epoll(IO多路复用)
asyncio是python用于解决异步io编程的一整套解决方案
tornado、gevent、twisted(scrapy, django channels)
torando(实现web服务器), django+flask(uwsgi, gunicorn+nginx)
tornado可以直接部署, nginx+tornado

import asyncio
import time  # 不再这使用同步阻塞的timeasync def get_html(url):print("start get url")await asyncio.sleep(2)# time.sleep(2) 不要这样写print("end get url")if __name__ == "__main__":start_time = time.time()loop = asyncio.get_event_loop()tasks = [get_html("http://www.imooc.com") for i in range(10)]loop.run_until_complete(asyncio.wait(tasks))print(time.time() - start_time)"""
start get url
start get url
start get url
start get url
start get url
start get url
start get url
start get url
start get url
start get url
end get url
end get url
end get url
end get url
end get url
end get url
end get url
end get url
end get url
end get url
2.001918077468872
"""

# 使用asyncio

import asyncio
import timefrom functools import partial  # 偏函数async def get_html(url):print("start get url")await asyncio.sleep(2)return "lewen"def callback(url, future):print(url)print("send callback email to lewen")if __name__ == "__main__":start_time = time.time()loop = asyncio.get_event_loop()  # 事件循环# task = asyncio.ensure_future(get_html("http://www.imooc.com")) # 任务的两种不同写法task = loop.create_task(get_html("http://www.imooc.com"))task.add_done_callback(partial(callback, "http://www.imooc.com"))loop.run_until_complete(task)print(task.result())"""
start get url
http://www.imooc.com
send callback email to lewen
lewen
"""

# 获取协程的返回值

import asyncio
import timeasync def get_html(url):print("start get url")await asyncio.sleep(2)print("end get url")if __name__ == "__main__":start_time = time.time()loop = asyncio.get_event_loop()tasks = [get_html("http://www.imooc.com") for i in range(10)]# loop.run_until_complete(asyncio.gather(*tasks))loop.run_until_complete(asyncio.wait(tasks))# print(time.time()-start_time)# gather和wait的区别# gather更加高层 high-level    分组group1 = [get_html("http://projectsedu.com") for i in range(2)]group2 = [get_html("http://www.imooc.com") for i in range(2)]group1 = asyncio.gather(*group1)group2 = asyncio.gather(*group2)# group2.cancel()   #取消loop.run_until_complete(asyncio.gather(group1, group2))print(time.time() - start_time)

# wait 和 gather

13.2 协程嵌套

13.3 call_soon、call_later、call_at、call_soon_threadsafe

import asynciodef callback(sleep_times, loop):print("success time {}".format(loop.time()))def stoploop(loop):loop.stop()# call_later, call_at
if __name__ == "__main__":loop = asyncio.get_event_loop()# 马上执行队列里面的task# loop.call_soon(callback, 4, loop)# loop.call_soon(stoploop, loop)# call_later() 等待多少秒后执行# loop.call_later(2, callback, 2, loop)# loop.call_later(1, callback, 1, loop)# loop.call_later(3, callback, 3, loop)# call_at()  在某一时刻执行now = loop.time()loop.call_at(now+2, callback, 2, loop)loop.call_at(now+1, callback, 1, loop)loop.call_at(now+3, callback, 3, loop)loop.run_forever()# loop.call_soon_threadsafe()

view

13.4 ThreadPoolExecutor+asyncio

# 使用多线程:在协程中集成阻塞io
# 数据库等阻塞式IO
import asyncio
from concurrent.futures import ThreadPoolExecutor
import socket
from urllib.parse import urlparsedef get_url(url):# 通过socket请求htmlurl = urlparse(url)host = url.netlocpath = url.pathif path == "":path = "/"# 建立socket连接client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# client.setblocking(False)client.connect((host, 80))  # 阻塞不会消耗cpu# 不停的询问连接是否建立好, 需要while循环不停的去检查状态# 做计算任务或者再次发起其他的连接请求client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format(path, host).encode("utf8"))data = b""while True:d = client.recv(1024)if d:data += delse:breakdata = data.decode("utf8")html_data = data.split("\r\n\r\n")[1]print(html_data)client.close()if __name__ == "__main__":import timestart_time = time.time()loop = asyncio.get_event_loop()executor = ThreadPoolExecutor(3)  # 线程池tasks = []for url in range(20):url = "http://www.baidu.com/s?wd={}/".format(url)task = loop.run_in_executor(executor, get_url, url)  # 将阻塞的放到执行器里面tasks.append(task)loop.run_until_complete(asyncio.wait(tasks))print("last time:{}".format(time.time() - start_time))# 将线程池直接应用到协程里面

13.5 asyncio模拟http请求

# coding=utf-8
# asyncio 没有提供http协议的接口 aiohttp
import asyncio
from urllib.parse import urlparseasync def get_url(url):# 通过socket请求htmlurl = urlparse(url)host = url.netlocpath = url.pathif path == "":path = "/"# 建立socket连接reader, writer = await asyncio.open_connection(host, 80)writer.write("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format(path, host).encode("utf8"))all_lines = []async for raw_line in reader:data = raw_line.decode("utf8")all_lines.append(data)html = "\n".join(all_lines)return htmlasync def main():tasks = []for url in range(20):url = "http://www.baidu.com/s?wd={}/".format(url)tasks.append(asyncio.ensure_future(get_url(url)))for task in asyncio.as_completed(tasks):result = await taskprint(result)if __name__ == "__main__":import timestart_time = time.time()loop = asyncio.get_event_loop()loop.run_until_complete(main())print('last time:{}'.format(time.time() - start_time))

13.6 future和task

future 结果容器

task 是 future 的子类,协程和future之间的桥梁,启动协程

13.7 asyncio同步和通信

total = 0async def add():# 1,dosomething1# 2.io操作# 1.dosomething3global totalfor i in range(100000):total += 1async def desc():global totalfor i in range(100000):total -= 1if __name__ == "__main__":import asynciotasks = [add(), desc()]loop = asyncio.get_event_loop()loop.run_until_complete(asyncio.wait(tasks))print(total)

# 不需要锁的情况

13.8 aiohttp实现高并发爬虫

gj13 asyncio并发编程相关推荐

  1. python asyncio 并发编程_asyncio并发编程

    一. 事件循环 1.注: 实现搭配:事件循环+回调(驱动生成器[协程])+epoll(IO多路复用),asyncio是Python用于解决异步编程的一整套解决方案: 基于asynico:tornado ...

  2. asyncio并发数_Python Futures并发编程详解

    无论哪门编程语言,并发编程都是一项很常用很重要的技巧.例如,爬虫就被广泛应用在工业界的各个领域,我们每天在各个网站.各个 App 上获取的新闻信息,很大一部分便是通过并发编程版的爬虫获得.正确合理地使 ...

  3. Python并发编程Asyncio

    目录 1. Asyncio是什么? (1)Sync与Async (2)Asyncio 工作原理 (3)Asyncio 用法 2. Asyncio是银弹吗? 3.多线程还是 Asyncio? 4.小结 ...

  4. asyncio 文件io高并发_python教程:使用 async 和 await 协程进行并发编程

    python 一直在进行并发编程的优化, 比较熟知的是使用 thread 模块多线程和 multiprocessing 多进程,后来慢慢引入基于 yield 关键字的协程. 而近几个版本,python ...

  5. python 异步io框架_Python并发编程之学习异步IO框架:asyncio 中篇(十)

    大家好,并发编程 进入第十章. 好了,今天的内容其实还挺多的,我准备了三天,到今天才整理完毕.希望大家看完,有所收获的,能给小明一个赞.这就是对小明最大的鼓励了. 为了更好地衔接这一节,我们先来回顾一 ...

  6. python并发编程:协程asyncio、多线程threading、多进程multiprocessing

    python并发编程:协程.多线程.多进程 CPU密集型计算与IO密集型计算 多线程.多进程与协程的对比 多线程 创建多线程的方法 多线程实现的生产者-消费者爬虫 Lock解决线程安全问题 使用线程池 ...

  7. python并发编程方法_Python Futures并发编程详解

    无论哪门编程语言,并发编程都是一项很常用很重要的技巧.例如,爬虫就被广泛应用在工业界的各个领域,我们每天在各个网站.各个 App 上获取的新闻信息,很大一部分便是通过并发编程版的爬虫获得. 正确合理地 ...

  8. 并发编程协程(Coroutine)之Gevent

    并发编程协程之Gevent Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate r ...

  9. 揭秘Python并发编程——协程

    原文链接:https://baijiahao.baidu.com/s?id=1649450510185145678&wfr=spider&for=pc Python并发编程一直是进阶当 ...

最新文章

  1. python 简易HTTP服务器搭建
  2. 数据结构 排序和查找
  3. win8换成linux桌面,Ubuntu/Linux Mint分分钟变Win8风
  4. OpenCASCADE绘制测试线束:图形命令之Axonometric观察器
  5. 测试一年多,上线就崩溃!微服务到底应该怎么测试?
  6. Java精确到毫秒获取时间的三种方法,以及适用场景
  7. mysql kafka binlog_为什么使用kafka处理mysql binlog?
  8. linux怎样判断线程是否暂停_怎样判断股市是否会继续下跌?
  9. tomcat调优方案
  10. FutureTask源码分析
  11. Eclipse内存溢出
  12. 从环境搭建探讨做事的方法
  13. Storm入门之第8章事务性拓扑
  14. 微软亚洲研究院20年20人
  15. Java之Base64
  16. CVPR2021目标跟踪汇总(一)
  17. mysql存储kv_图数据库的优点有什么?同mysql和kv数据库相比有什么本质不同?
  18. el 表达式 判断字符串是否相等
  19. 基于云创部署spark
  20. InnoSetup的简繁体中文语言文件ChineseSimplified.isl和ChineseTraditional.isl

热门文章

  1. java 比较算法_JAVA排序算法实现和比较:冒泡,桶,选择,快排,归并
  2. 更改应用程序图标_基于安卓11的ColorOS 11的主要功能和更改日志
  3. mysql datetime 转date_详解MySQL如何按表创建千万级的压测数据
  4. vs 创建控制器 一直收集信息_日产Pro-Pilot的ADAS控制器拆解
  5. web页面刷不出来 白色_今日头条连接超时刷不出来解决方案
  6. 对hash签名失败_详解Vue开发微信H5微信分享签名失败问题解决方案
  7. 储存外部资源的Android项目子目录,Android资源使用
  8. python 单元测试 工具_Django单元测试工具test client使用详解
  9. docker安装elasticsearch_Docker 安装 ElasticSearch
  10. 3dmax挤出制作窗花_「教程」3DMAX制作藤编家具模型,超实用教程,收藏备用