用自己的手机做网站企业网站推广建议
2026/2/17 23:54:38 网站建设 项目流程
用自己的手机做网站,企业网站推广建议,网站需要去工信部做备案吗,seo性能优化Day 39#xff1a;【99天精通Python】异步编程 (AsyncIO) 上篇 - 协程的魔法 前言 欢迎来到第39天#xff01; 在前面的课程中#xff0c;我们学习了多线程。线程虽然好用#xff0c;但它是由操作系统负责调度的。操作系统很忙#xff0c;它要在几千个线程之间来回切换【99天精通Python】异步编程 (AsyncIO) 上篇 - 协程的魔法前言欢迎来到第39天在前面的课程中我们学习了多线程。线程虽然好用但它是由操作系统负责调度的。操作系统很忙它要在几千个线程之间来回切换Context Switch这需要消耗不少资源。当并发量达到上万级别时线程切换的开销就会拖垮系统。协程 (Coroutine)是一种比线程更轻量级的存在。线程操作系统决定什么时候切换你无法控制。协程程序自己决定什么时候切换“我等数据的时候你先干别的”。Python 3.4 引入了asyncio库Python 3.5 引入了async和await关键字标志着 Python 进入了原生异步编程时代。这是高性能网络服务器如 FastAPI, Tornado的基石。本节内容同步 (Sync) vs 异步 (Async)async与await关键字事件循环 (Event Loop)运行协程asyncio.run()并发执行asyncio.gather()实战体验光速睡眠一、同步 vs 异步1.1 同步 (Synchronous)代码从上到下依次执行。如果第一行卡住了比如下载文件第二行就得干等。importtimedeftask(name):time.sleep(1)# 阻塞 1 秒print(f{name}完成)task(A)task(B)# 总耗时: 2 秒1.2 异步 (Asynchronous)当第一行卡住等待 I/O时程序会自动挂起它去执行第二行。等第一行结果回来了再恢复执行。# 伪代码逻辑awaittask(A)# 你先下着我去干别的awaittask(B)# 你也下着# 总耗时: 约 1 秒 (因为是同时等的)二、Hello AsyncIO2.1 定义协程 (async def)使用async def定义的函数不再是普通函数而是一个协程函数。调用它不会立即执行而是返回一个协程对象。importasyncioasyncdefsay_hello():print(Hello)returnWorld# 直接调用不会执行打印# coroutine say_hello()# print(coroutine) # coroutine object ...2.2 运行协程 (asyncio.run)要让协程跑起来必须把它扔进事件循环 (Event Loop)。Python 3.7 提供了最简单的入口asyncio.run()。importasyncioasyncdefmain():print(开始)# await 后面必须跟一个可等待对象 (Coroutine, Task, Future)# 这里不能用 time.sleep要用 asyncio.sleepawaitasyncio.sleep(1)print(结束)if__name____main__:asyncio.run(main())注意asyncio.sleep(1)是非阻塞的睡眠而time.sleep(1)是阻塞的。在协程中千万别用time.sleep否则整个程序都会卡死三、并发执行asyncio.gather如果我们按顺序写两个await它们还是串行的。asyncdefmain():awaittask(1)# 等它做完awaittask(2)# 再做这个# 依然是串行没体现出异步优势要实现并发我们需要告诉事件循环“把这几个任务一起安排了”。使用asyncio.gather()。实战对比同步 vs 异步我们模拟烤面包2秒和煮咖啡3秒。importasyncioimporttime# --- 异步任务 ---asyncdefmake_toast():print(开始烤面包...)awaitasyncio.sleep(2)# 模拟耗时 I/Oprint(面包烤好了)returnToastasyncdefmake_coffee():print(开始煮咖啡...)awaitasyncio.sleep(3)print(咖啡煮好了)returnCoffeeasyncdefmain():starttime.time()print(--- 早餐开始 ---)# 并发执行两个任务# gather 会等待所有任务完成并按顺序返回结果列表resultsawaitasyncio.gather(make_toast(),make_coffee())endtime.time()print(f--- 早餐结束耗时:{end-start:.2f}秒 ---)print(f结果:{results})if__name____main__:asyncio.run(main())运行结果--- 早餐开始 --- 开始烤面包... 开始煮咖啡... (过了2秒) 面包烤好了 (又过1秒) 咖啡煮好了 --- 早餐结束耗时: 3.01 秒 --- 结果: [Toast, Coffee]如果用同步方式需要 235 秒。异步方式只用了 3 秒取决于最长的那个任务。四、深入理解await 到底在干嘛await关键字的作用是挂起当前协程暂停执行。交出控制权给事件循环让它去调度其他协程。等待后面的对象如sleep或网络请求返回结果。恢复执行。这就像你在餐厅点菜await 点菜()你告诉服务员要什么服务员去厨房下单交出控制权。服务员去服务其他桌的客人调度其他任务。厨房做好了IO完成服务员把菜端给你恢复执行。五、常见的坑 (必看)坑1在协程里写了阻塞代码这是新手最容易犯的错。asyncdefbad_coroutine():print(开始)# time.sleep 是阻塞的它会霸占 CPU不让出控制权。# 导致整个线程卡住其他协程也跑不了。importtime time.sleep(5)print(结束)原则在async def函数里所有耗时操作都必须是异步的支持await的比如asyncio.sleep或者异步库aiohttp,aiomysql。不能用普通的requests,time.sleep。坑2忘记写 awaitasyncdefmain():# 这样写只会创建一个协程对象但不会执行它# RuntimeWarning: coroutine xxx was never awaitedasyncio.sleep(1)# 正确写法awaitasyncio.sleep(1)六、小结异步编程 AsyncIO核心概念关键字运行模式Event Loop (调度中心)Coroutine (协程对象)非阻塞 I/Oasync def (定义)await (挂起/等待)asyncio.run() (入口)asyncio.gather() (并发)关键要点协程是单线程并发靠的是合作式调度自己主动让出 CPU。async def定义协程await调度协程。asyncio.gather是并发执行的神器。千万别在协程里用阻塞代码如time.sleep,requests否则一核有难八核围观。七、课后作业异步倒计时编写一个协程countdown(name, n)每秒打印一次倒计时n, n-1, … 1。并发运行 3 个倒计时任务比如 A倒数3秒B倒数5秒。效率对比编写一个普通的函数sync_cal()使用time.sleep(1)和一个协程async_cal()使用asyncio.sleep(1)。分别循环调用它们 5 次同步循环 vsgather并发对比总耗时。思考题为什么计算密集型任务如算圆周率不适合用asyncio提示回顾一下 GIL 和单线程的本质。下节预告Day 40异步编程 (AsyncIO) 下篇 - aiohttp- 既然不能用requests那在协程里怎么发网络请求我们将学习 Python 最强的异步网络库aiohttp体验每秒几千次请求的快感系列导航上一篇Day 38 - 线程池与进程池下一篇Day 40 - 异步编程AsyncIO下待更新

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询