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()
posted @ 2023-03-12 16:08  __username  阅读(13)  评论(0编辑  收藏  举报

本文作者:DIVMonster

本文链接:https://www.cnblogs.com/guangzan/p/12886111.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。