回到首页

python的await语句使用解释

import asyncio
import requests
import time

async def result(url):
    # await request_url(url) # 第一条语句
    # res = await request_url(url) # 第二条语句
    await request_url1(url) # 第三条语句
    print(f'-----{url}')
    # print(url, res)

async def request_url(url):
    res = requests.get(url)
    print(url)
    await asyncio.sleep(2)
    print("execute_time:", time.time() - start)
    return res

async def request_url1(url):
    res=requests.get(url)
    print(url)
    time.sleep(2)
    print('execute_time:',time.time()-start)
    return res

url_list = ["https://www.csdn.net/",
            "https://blog.csdn.net/qq_43380180/article/details/111573642",
            "https://www.baidu.com/",
            ]

start = time.time()
print(f"start_time:{start}\n")

task = [result(url) for url in url_list]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(task))

endtime = time.time() - start
print("\nendtime:", time.time())
print("all_execute_time:", endtime)

测试了代码中注释有“第一条语句”、“第二条语句”和“第三条语句”的语句发挥的作用,测试时取消测试语句的注释,其他两条语句被注释掉。首先,第一条语句和第二条语句的效果一样,在理清await的作用前我总有种幻想,是result会不管request_url的执行过程,发布个request_url任务直接向下执行,而结果和幻想结果不一致,我猜测是因为有返回值,解释器需要等待返回值的赋值,故第一条语句相比第二条语句去掉了返回值,测试结果仍没变化,经过思考,明白了这是协程,异步的进程或线程才会有我幻想的结果。只有第三条语句被执行时,程序的三个事件顺序执行,休眠两秒的动作会被执行三次。在执行第二条语句时,该程序的含义是发布三项访问url的并行执行的任务,每个任务并列地睡眠两秒。

展示执行不同语句的打印结果,第一条语句和第二条语句结果一样,所以只展示执行第二条语句的实验二和执行第三条语句的实验三:
实验二

start_time:1673699240.3729575

C:\Users\tellw\test\test1.py:35: DeprecationWarning: There is no current event loop
  loop = asyncio.get_event_loop()
https://blog.csdn.net/qq_43380180/article/details/111573642
https://www.csdn.net/
https://www.baidu.com/
execute_time: 2.302398920059204
-----https://blog.csdn.net/qq_43380180/article/details/111573642
execute_time: 2.583828926086426
-----https://www.csdn.net/
execute_time: 2.709165573120117
-----https://www.baidu.com/

endtime: 1673699243.0838816
all_execute_time: 2.7109241485595703

实验三
start_time:1673699223.1047676

C:\Users\tellw\test\test1.py:35: DeprecationWarning: There is no current event loop
  loop = asyncio.get_event_loop()
https://blog.csdn.net/qq_43380180/article/details/111573642
execute_time: 2.3865320682525635
-----https://blog.csdn.net/qq_43380180/article/details/111573642
https://www.csdn.net/
execute_time: 4.672637462615967
-----https://www.csdn.net/
https://www.baidu.com/
execute_time: 6.810583829879761
-----https://www.baidu.com/

endtime: 1673699229.9167387
all_execute_time: 6.811971187591553

对于异步线程的讨论:

import threading
import time

print(time.ctime())

def func(name,sec):
	time.sleep(sec)
	print(name,time.ctime())

t1=threading.Thread(target=func,args=('1',1))
t2=threading.Thread(target=func,args=('2',2))

t1.start()
t2.start()

# t1.join()
# t2.join()

print('main end',time.ctime())
上述代码执行结果
Sat Jan 14 20:17:53 2023
main end Sat Jan 14 20:17:53 2023
1 Sat Jan 14 20:17:54 2023
2 Sat Jan 14 20:17:55 2023
子线程睡1秒,子线程睡2秒,两个子线程睡两秒,主线程不睡,对应主线程调起其他子线程后自己忙自己的事的幻想,按理说主线程执行完后仍会等待其他子线程完成工作
当执行t1.join()和t2.join()代码时,主线程阻塞住等到所有子线程执行完成返回在执行主线程的工作。
Sat Jan 14 20:18:21 2023
1 Sat Jan 14 20:18:22 2023
2 Sat Jan 14 20:18:23 2023
main end Sat Jan 14 20:18:23 2023

参考链接:Python 异步 async/await(进阶详解)
Python threading实现多线程 基础篇

本文创建于2023.1.14/20.45,修改于2023.1.14/20.45