100python异步asyncio
3.12
# coding=gbk
# -*- coding:uft-8 -*-
# @Time: 2023/3/12
# @motto: Become a code whiz
# @FileName: python异步之asyncio
import asyncio
import random
async def func1():
print("运行func1")
await asyncio.sleep(random.uniform(1.0, 8.0) / 10)
print(2)
async def func2():
print("运行func2")
await asyncio.sleep(random.uniform(1.0, 8.0) / 10)
print(4)
async def func3():
print("运行func3")
await asyncio.sleep(random.uniform(1.0, 8.0) / 10)
print(6)
async def main():
tasks = [func1(), func2(), func3()]
await asyncio.gather(*tasks)
if __name__ == '__main__':
asyncio.run(main())
运行结果(后三随机)
如果在Python3.7之前,你需要手动显示调用当前时间循环
loop = asyncio.get_event_loop()
loop.run_until_complete(....)
loop.close()
而在Python3.7之后,有另外一种形式
async def task_exect():
tasks=[func1(),func2(),func3()]
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(task_exect())
3.15修改
一、asyncio
学习asyncio之前,我们先来理清楚同步/异步的概念:
同步是指完成事务的逻辑,先执行第一个事务,如果阻塞了,会一直等待,直到这个事务完成,再执行第二个事务,顺序执行。
异步是和同步相对的,异步是指在处理调用这个事务的之后,不会等待这个事务的处理结果,直接处理第二个事务去了,通过状态、通知、回调来通知调用者处理结果
同步
def hello():
time.sleep(1)
def run():
for i in range(5):
hello()
print("hello world:%s" % time.time())
if __name__ == '__main__':
run()
'''hello world:1678855393.7920215
hello world:1678855394.7992227
hello world:1678855395.808516
hello world:1678855396.8230665
hello world:1678855397.8330507
'''
异步
# 第一种写法
import time
import asyncio
async def hello():
await asyncio.sleep(1)
print('hello world:%s' % time.time())
async def task_exect():
tasks=[hello() for i in range(5)]
await asyncio.gather(*tasks)
if __name__ == '__main__':
asyncio.run(task_exect())
# 第二张写法
import time
import asyncio
# 定义异步函数
async def hello():
await asyncio.sleep(1)
print('Hello World:%s' % time.time())
if __name__ =='__main__':
loop = asyncio.get_event_loop()
tasks = [hello() for i in range(5)]
loop.run_until_complete(asyncio.wait(tasks))
'''hello world:1678856163.7185452
hello world:1678856163.7185452
hello world:1678856163.7185452
hello world:1678856163.7185452
hello world:1678856163.7185452
'''
如果在Python3.7之前,你需要手动显示调用当前时间循环
loop = asyncio.get_event_loop()
loop.run_until_complete(....)
loop.close()
而在Python3.7之后,有另外一种形式
async def task_exect():
tasks=[func1(),func2(),func3()]
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(task_exect())
更多参考:https://www.cnblogs.com/shenh/p/9090586.html
二、aiohttp
如果需要并发http请求怎么办呢,通常是用requests,但requests是同步的库,如果想异步的话需要引入aiohttp。这里引入一个类,from aiohttp import ClientSession,首先要建立一个session对象,然后用session对象去打开网页。session可以进行多项操作,比如post, get, put, head等。
基本用法:
async with ClientSession() as session:
async with session.get(url) as response:
aiohttp异步实现的例子:
import asyncio
from aiohttp import ClientSession
tasks = []
url = "https://www.baidu.com/{}"
async def hello(url):
async with ClientSession() as session:
async with session.get(url) as response:
response = await response.read()
print(response)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(hello(url))
#coding:utf-8
import time,asyncio,aiohttp
url = 'https://www.baidu.com/'
async def hello(url,semaphore):
async with semaphore:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.read()
async def run():
semaphore = asyncio.Semaphore(500) # 限制并发量为500
to_get = [hello(url.format(),semaphore) for _ in range(1000)] #总共1000任务
await asyncio.wait(to_get)
if __name__ == '__main__':
# now=lambda :time.time()
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
loop.close()
本文来自博客园,作者:__username,转载请注明原文链接:https://www.cnblogs.com/code3/p/17208373.html