python并发之协程_python并发编程之协程

由线程遗留下的问题:GIL导致多个线程不能真正的并行,CPython中多个线程不能并行

单线程实现并发:切换+保存状态

第一种方法:使用yield,yield可以保存状态。yield的状态保存与操作系统保存线程状态很像,但是yield是代码级控制的,更更轻量级。

ContractedBlock.gif

ExpandedBlockStart.gif

# 两个计算任务一个采用生成器切换并发执行 一个直接串行调用

import time

def task1():

a= 0

for i in range(10000000):

a+=iyielddef task2():

g=task1()

b= 0

for i in range(10000000):

b+= 1next(g)

s=time.time()

task2()

print("并发执行时间",time.time()-s)

# 单线程下串行执行两个计算任务 效率反而比并发高 因为并发需要切换和保存

def task1():

a= 0

for i in range(10000000):

a+=i

def task2():

b= 0

for i in range(10000000):

b+= 1s=time.time()

task1()

task2()

print("串行执行时间",time.time()-s)

View Code

可以看出,对于纯计算任务而言,单线程并发反而使效率降低。而且使用yield来切换使得代码结构混乱。

第二种方法:使用greenlet模块,仅仅是对yield在封装。依然不能对检测IO操作。

ContractedBlock.gif

ExpandedBlockStart.gif

import greenlet

def task1(name):

print("%s task1 run1" %name)

g2.switch(name) # 切换至任务2

print("task1 run2")

g2.switch() # 切换至任务2

def task2(name):

print("%s task2 run1" %name)

g1.switch() # 切换至任务1

print("task2 run2")

g1=greenlet.greenlet(task1)

g2=greenlet.greenlet(task2)

g1.switch("jerry") # 为任务传参数

View Code

第三种办法:协程

协程: 指的是一个线程完成并发执行,协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的

强调:

python的线程始于内核级别的,即由操作系统控制调度(遇到IO或执行事件过长就会被迫交出CPU执行权限,切换到其他线程)

单线程内开启协程,一旦遇到IO,就会从应用程序级别控制切换,以此来提升效率

优点:

1. 协程的切换开销更小,属于程序级别的切换,更加轻量级

2. 单线程内就可以实现并发的效果,最大限度的利用CPU

缺点:

1. 协程本质是单线程并发,无法利用多核,可以是一个程序开多个进程,每个进程内开启多个线程,每个线程内开启协程

2. 一旦协程遇到阻塞,将会阻塞整个线程

在CPython中,如果是计算密集型,使用协程是无法提高效率,反而因为切换任务导致效率较低,只能靠进程。IO密集型 多线程会比多进程效率高,因为多线程开销比多进程小的多。

使用模块:gevent,gevent既可以单线程实现并发,又可以检测IO操作

ContractedBlock.gif

ExpandedBlockStart.gif

import gevent

import timefromgevent import monkey # 导入monkey补丁

monkey.patch_all() # 打补丁

def task1():

print("task1 run")

# gevent.sleep(3)

time.sleep(3)

print("task1 over")

def task2():

print("task2 run")

# gevent.sleep(1)

time.sleep(1)

print("task2 over")

g1=gevent.spawn(task1)

g2=gevent.spawn(task2)

# g1.join()

# g2.join()

gevent.joinall([g1,g2])

View Code

需要注意:

协程执行时必须对协程对象调用join函数(join让主线程等待协程任务完成,因为主线程一旦结束,协程任务就不执行了。反过来说 要保证协程任务正常执行结束 必须保证主线程没有结束)

如果有多个任务,随便调用哪一个的join都会并发执行所有任务,但是需要注意如果有一个存在IO操作的任务没有被join,该任务将无法正常执行完毕。

monkey补丁的原理,把原始的阻塞模块替换为修改后的非阻塞模块,来实现IO自定切换,所以打补丁的位置尽量要放在导入阻塞模块之前

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
08-10
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值