2026/4/18 15:56:17
网站建设
项目流程
wordpress 短代码失效,怎么优化一个网站,私密浏览器免费版片视频动漫,wordpress分类静态一、协程介绍概念#xff1a;单线程下的开发#xff0c;又称微线程#xff0c;纤程。英文名叫 Coroutine。协程是 python 中另外一种实现多任务的方式#xff0c;只不过比线程更小、占用更小执行单元#xff08;理解为需要的资源#xff09;。它自带 CPU 上下文。这样只要…一、协程介绍概念单线程下的开发又称微线程纤程。英文名叫 Coroutine。协程是 python 中另外一种实现多任务的方式只不过比线程更小、占用更小执行单元理解为需要的资源。它自带 CPU 上下文。这样只要在合适的时机我们可以把一个协程切换到另一个协程。只要这个过程中保存或恢复 CPU 上下文那么程序还是可以运行的。线程和进程的操作是由程序触发系统接口最后的执行者是系统协程的操作则是程序员。简单实现协程def task1(): while True: yield 正在执行任务1 def task2(): while True: yield 正在执行任务2 if __name__ __main__: while True: print(next(task1())) print(next(task2())) # 输出一个死循环应用场景如果一个线程里面有IO 操作比较多的时候可以用协程IOInput/Output常见的IO操作文件操作、网络请求适合高并发处理二、greenlet 的使用介绍greenlet是一个由C语言实现的协程模块。通过设置switch来实现任意函数之间的切换安装与卸载命令win r 后输入cmd安装greenletpython -m pip install greenlet卸载greenletpython -m) pip uninstall greenlet查看安装包python -m pip list注意greenlet属于手动切换当遇到IO操作程序会阻塞而不能进行自动切换通过greenlet实现任务的切换导入模块 from greenlet import greenlet创建协程对象调用switchfrom greenlet import greenlet def sing(): print(正在唱歌...) g2.switch() #切换到g2中去运行 print(唱完歌了) def dance(): print(正在跳舞...) print(跳完舞了) g1.switch()#切换到g1中去运行 if __name__ __main__: # 创建协程对象 g1 greenlet(sing) g2 greenlet(dance) g1.switch() #切换到g1中去运行 # 正在唱歌... # 正在跳舞... # 跳完舞了 # 唱完歌了三、gevent 的使用介绍是一个基于协程Coroutine的 Python 网络编程库它以 greenlet 为底层实现解决了 greenlet 需要手动切换的痛点能够自动检测 IO 操作并切换任务从而实现高效的并发编程尤其适合处理大量网络请求、IO 密集型任务比如爬虫、接口测试、后端服务并发处理等。安装与卸载的命令安装 geventpython -m pip install gevent卸载 greenletpython -m) pip uninstall gevent查看安装包python -mpip list注意文件命名不要和第三方模块活内置模块重名使用导入gevent模块 import geventgevent.spawn(函数名)创建协程对象gevent.sleep()耗时操作gevent.join()阻塞等待某个协程执行结束gevent.joinall()等待所有协程对象都执行结束再退出参数是一个协程对象列表import gevent def sing(): print(正在唱歌...) gevent.sleep(2) print(唱完歌了) def dance(): print(正在跳舞...) gevent.sleep(3) print(跳完舞了) if __name__ __main__: g1 gevent.spawn(sing) g2 gevent.spawn(dance) g1.join() g2.join() # 正在唱歌... # 正在跳舞... # 唱完歌了 # 跳完舞了import gevent def sing1(name): for i in range(3): gevent.sleep(1) print(f{name}正在唱歌第{i}次) if __name__ __main__: gevent.joinall([gevent.spawn(sing1,小王),gevent.spawn(sing1,小李)]) # 小王正在唱歌第0次 # 小李正在唱歌第0次 # 小王正在唱歌第1次 # 小李正在唱歌第1次 # 小王正在唱歌第2次 # 小李正在唱歌第2次其他补充gevent.spawn() 返回的协程对象通过 value 属性可以获取函数的返回值需等待协程执行完成后才能获取------g.value使用 gevent.with_timeout() 可以为协程设置超时时间超过时间未执行完成则抛出异常。------gevent.with_timeout(2, 函数名)Monkey补丁拥有在模块运行时替换的功能monkey.patch_all() 全量替换将time.sleep()代码替换成gevent.sleep()实现耗时操作。注意一定放在被打补丁的前面from gevent import monkey import time,gevent monkey.patch_all() # 将time.sleep()代码替换成gevent.sleep()实现耗时操作 def sing1(name): for i in range(3): time.sleep(1) print(f{name}正在唱歌第{i}次) if __name__ __main__: gevent.joinall([ gevent.spawn(sing1,小李), gevent.spawn(sing1,小张) ]) # 小李正在唱歌第0次 # 小张正在唱歌第0次 # 小李正在唱歌第1次 # 小张正在唱歌第1次 # 小李正在唱歌第2次 # 小张正在唱歌第2次monkey.patch_time()仅替换 time 模块monkey.patch_socket()仅替换 socket 模块适用场景高并发网络请求I/O 密集型典型场景import gevent from gevent import monkey import requests import time # 第一步先启用猴子补丁再导入/使用其他库 monkey.patch_all() # 定义网络请求任务 def fetch_url(url, name): print(f任务 {name} 开始请求{url}) try: # requests 是同步库但 socket 被猴子补丁改造变为异步请求 response requests.get(url, timeout10) print(f任务 {name} 请求成功状态码{response.status_code}响应长度{len(response.text)}) except Exception as e: print(f任务 {name} 请求失败{str(e)}) # 要请求的多个 URL urls [ https://www.baidu.com, https://www.taobao.com, https://www.jd.com, https://www.github.com, https://www.stackoverflow.com ] # 记录开始时间 start_time time.time() # 1. 创建协程列表为每个 URL 创建一个协程 greenlets [] for idx, url in enumerate(urls, 1): g gevent.spawn(fetch_url, url, fURL-{idx}) greenlets.append(g) # 2. 等待所有协程执行完成 gevent.joinall(greenlets) # 记录结束时间 end_time time.time() print(f\n所有请求执行完毕总耗时{end_time - start_time:.2f} 秒)注意事项gevent 仅适用于 I/O 密集型任务网络请求、文件读写、数据库操作等不适用于 CPU 密集型任务因为协程切换依赖 I/O 阻塞CPU 密集型任务不会触发切换会导致单个协程占用整个 CPU 资源。猴子补丁必须在导入其他模块之前执行否则可能无法正常替换同步方法。gevent 是单线程的所有协程都运行在同一个主线程中因此无需考虑线程安全问题但多进程场景仍需考虑。如果需要结合多进程处理 CPU 密集型任务可以使用 gevent multiprocessing 组合。总结gevent 是基于协程的异步网络库核心优势是轻量、高效适合处理高并发 I/O 密集型任务。核心用法通过 gevent.spawn() 创建协程、gevent.joinall() 等待协程执行通过 monkey.patch_all() 实现同步代码的异步改造。关键注意猴子补丁需提前执行gevent 不适合 CPU 密集型任务协程切换依赖 I/O 阻塞触发。四、总结进程、线程和协程线程是 CPU 调度的基本单位进程是资源分配的基本单位进程、线程和协程对比进程切换需要的资源最大效率最低线程切换需要的资源一般效率一般协程切换需要的资源最小效率高多线程适合 IO 密集型操作 (文件操作、爬虫)多进程适合 CPU 密集型操作 (科学及计算、对视频进行高清解码、计算圆周率)进程、线程、协程都是可以完成多任务的可以根据自己实际开发的需要选择使用。进程、线程、协程核心区别对照表对比维度进程线程协程资源分配资源分配的基本单位拥有独立的内存空间、文件句柄等系统资源资源共享的基本单位同一进程内的线程共享进程的内存和资源完全共享所在线程的资源仅保存自身执行上下文寄存器、栈调度主体由操作系统内核调度切换开销大需保存 / 恢复进程上下文由操作系统内核调度切换开销中等需保存 / 恢复线程上下文由用户程序如gevent、asyncio调度切换开销极小仅需切换函数栈切换开销最大涉及内核态切换、内存映射刷新中等涉及内核态切换但资源共享减少了数据拷贝最小用户态切换无内核参与并发能力受限于系统进程数上限并发数较低通常数百到数千受限于系统线程数上限并发数中等通常数千到数万极高单线程内可支持数万到数百万协程适用场景CPU 密集型任务如科学计算、视频解码、需要隔离资源的场景I/O 密集型任务如网络请求、文件读写、多任务并行计算高并发 I/O 密集型任务如高并发爬虫、微服务接口通信方式需依赖进程间通信IPC如管道、消息队列、共享内存直接读写共享变量需加锁保证线程安全直接读写变量单线程内无锁问题多线程需额外处理系统开销高每个进程独立占用内存和系统资源中线程共享进程资源但仍需内核维护线程表极低仅用户态上下文无内核额外开销崩溃影响单个进程崩溃不影响其他进程操作系统隔离单个线程崩溃会导致整个进程崩溃资源共享单个协程崩溃仅影响所在线程不影响进程