1.并发、并行、同步、异步、阻塞、非阻塞

并发:是指在同一个时间段内,有几个程序都处于启动运行到运行结束之间

并行:在同一个时间点上,有几个程序同时运行

同步:当一个同步操作发出去后,调用者一直等待返回消息结果,才能进行后续的操作 比如操作文件 打开文件 读取文件 都是同步操作

异步: 当一个异步操作发出去后,调用者不能立刻得到消息结果 创建线程 都是异步操作

阻塞:调用结果返回之前,当前线程会被挂起来,一直处于等待消息通知,不能执行其他业务

非阻塞:调用结果返回之前,该函数不会阻塞当前线程 而立刻返回

2.IO多路复用select、poll、epoll

select

它通过一个select()系统调用来监视多个文件描述符,当select()返回后,该数组中就绪的文件描述符会被内核修改标志位,使进程能够获得这些文件描述符,从    而进行后续的修改

缺点:单个进程能够监视的文件描述符的数量存在最大限制 一般1024

poll

本质跟select()没有区别 但是poll没有限制,使用的是链表存储

epoll

epoll同样只告知那些就绪的文件描述符,而且当我们调用epoll_wait()获得就绪文件描述符时,返回的不是实际的描述符,而是一个代表就绪描述符数量的    值,你只需要去epoll指定的一个数组中依次取得相应数量的文件描述符即可,这里也使用了内存映射(mmap)技术,这样便彻底省掉了这些文件描述符    在系统调用时复制的开销。

另一个本质的改进在于epoll采用基于事件的就绪通知方式。在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,    而poll事先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描        述符,当进程调用epoll_wait()时便得到通知。

epoll实列

1 importselectors,socket2 defaccept(sock, mask):3 conn, addr =sock.accept()4 print('accepted{}from{}'.format(conn,addr))5 conn.setblocking(False)6 sel.register(conn,selectors.EVENT_READ, read)7

8 defread(conn, mask):9 data = conn.recv(1024)10 ifdata:11 print('echoing{}to{}'.format(repr(data),conn))12 else:13 print('closing',conn)14 sel.unregister(conn)15 conn.close()16 sel =selectors.DefaultSelector()17 server =socket.socket()18 server.bind(('localhost', 9999))19 server.listen(500)20 server.setblocking(False)21 sel.register(server, selectors.EVENT_READ, accept) #注册事件,只要来一个连接就调accept这个函数,

22

23 whileTrue:24 events = sel.select()#这个select,看起来是select,有可能调用的是epoll,看你操作系统是Windows的还是Linux的

25 #默认阻塞,有活动连接就返回活动连接列表

26 print('事件',events)27

28 for key,mask inevents:29 callback =key.data30 callable(key.fileobj, mask)

View Code

客户端

importsocket,sys

server_address= ('localhost', 9999)#创建100个 TCP/IP socket实例

socks = [ socket.socket(socket.AF_INET, socket.SOCK_STREAM) for i in range(100)]#连接服务端

print('connecting to %s port %s' %server_address)for s insocks:

s.connect(server_address)

s.send(b'kehuduan')

data= s.recv(1024)print('服务端回来的数据{}'.format(data))if notdata:print('连接失败')

s.close()

3.什么是协成

可以暂停的函数(可以向暂停的地方传入值)

4.生成器

内含yiled关键字的函数

send方法

向生成器发送一个值,随后恢复执行

generator.send(value)

value参数是send方法向生成器发送的值,这个值作为当前yiled表达式的结果

随后生成器恢复执行 直到下一个yiled

defgen_func():#1 可以产出值 2 可以接受值

yield 333t= yield 'www.baidu.com'

print(t)yield 2

yield 3

yield 4

return 'bobby'

if __name__ == '__main__':

gen=gen_func()#启动生成器方式两种 nex () send

gen.send(None)#gen.close()会触发一次

#gen.throw(Exception,'异常')抛出异常

#send方法可以传递值 进入生成器内部,同时还可以重启生成器执行到下一个yiled位置

next(gen)

ret= gen.send('888')print(ret)print(next(gen))print(next(gen))

View Code

thorw方法详解

在生成器暂停的地方抛出类型为type的异常

defgen():

n=0whileTrue:try:yieldn

n+= 1

print('n的值{}'.format(n))exceptZeroDivisionError:print('铺货到异常ZerDivisionError')

g=gen()

ret=next(g)print('第一次的值{}'.format(ret))

ret=g.throw(ZeroDivisionError)print('第二次的值{}'.format(ret))

之所以第二次yield 的返回值还是 0,是因为在第一次 yield 的地方抛出了 ZeroDivisionError 异常,而该异常被 except 捕获,跳过了 n += 1的步骤。

在except 异常处理器中也可以看到,n 并没有改变,仍然是 0。

View Code

没有捕获并处理 throw 传入的异常,异常会回传给调用方。

def gen():

n = 0

while True:

yield n

n += 1

print('n的值{}'.format(n))

g = gen()

ret = next(g)

print('第一次的值{}'.format(ret))

try:

ret = g.throw(ZeroDivisionError)

except ZeroDivisionError:

print('第二次的值{}'.format(ret))

next(g)#对于已经通过抛出异常而退出的生成器再使用 next(g) 会持续抛出 StopIteration 异常。

生成器退出时没有 yield 新值,会抛出 StopIteration 异常。

def gen():

try:

yield 1

except Exception as e:

pass

yield 2

g = gen()

ret = next(g)

print('第一次的值{}'.format(ret))

ret = g.throw(TypeError, '类型错误哟')

# 虽然捕获并处理了 throw 传入的异常,但是由于处理完之后生成器没有后续语句而退出运行,而且并没有 yield 新值,所以会自动抛出一个 StopIteration 异常。

# 如果把 yield 2 注释打开,则不会抛出 StopIteration 异常,因为此时生成器暂停并返回了 2。

close方法

作用:在生成器函数暂停的地方抛出一个 GeneratorExit 异常。

这并不等价于 generator.throw(GeneratorExit),后面会说原因。

如果生成器抛出 StopIteration 异常(不管是由于正常退出还是因为该生成器已经关闭),或者抛出 GeneratorExit 异常(不捕获该异常即  可),close 方法不传递该异常,直接返回到调用方。而生成器抛出的其他异常会传递给调用方。

GeneratorExit 异常的产生意味着生成器对象的生命周期已经结束,因此生成器方法后续语句中不能再有 yield,否则会产生         RuntimeError。(而 throw 方法是期待一个 yield 返回值的,如果没有,则会抛出 StopIteration 异常。)

对于已经正常退出或者因为异常退出的生成器对象,close 方法不会进行任何操作。

第一种情况:不捕获 GeneratorExit 异常,close 方法返回调用方,不传递该异常。

defgen():yield 1

yield 2

yield 3g=gen()

ret=next(g)print('第一次的值{}'.format(ret))

g.close()

next(g)

View Code

第二种情况:生成器自然退出抛出 StopIteration 异常,该异常不会传递给调用方,close 方法正常返回。

defgen():try:yield 1

exceptGeneratorExit:print('生成器结束')

g=gen()

ret=next(g)print('第一次的值{}'.format(ret))

g.close()

View Code

第三种情况:在 GeneratorExit 抛出后还有 yield 语句,会产生 RuntimeError。

defgen():try:yield 1

exceptGeneratorExit:print('生成器结束')yield 2g=gen()

ret=next(g)print('第一次的值{}'.format(ret))

g.close()

View Code

5.yiled from

3.3中新增加的特性

yiled from后面可以是迭代器 可迭代对象 甚至是生成器

#使用yield

def gen(*args, **kw):for it inargs:for va init:yieldva

li= [1,2,3,4]

di= {'name':'gaofei','age':'25'}

tu= (6,7,8,9)

g=gen(li,di,tu)print(next(g))

View Code

#使用yield from

def gen(*args, **kw):for it inargs:yield fromit

li= [1,2,3,4]

di= {'name':'gaofei','age':'25'}

tu= (6,7,8,9)

g=gen(li,di,tu)print(next(g))

View Code

生成器的嵌套

defaverage_gen():

total=0

count=0

average=0whileTrue:

new_num= yieldaverage

count+= 1

print(count)

total+=new_numprint(total)

average= total/countdefproxy_gen():whileTrue:yield fromaverage_gen()defmain():

prox=proxy_gen()print(next(prox))print(prox.send(10))print(prox.send(20))if __name__=="__main__":

main()

View Code

概念

1.调用方 调用委派生成器的客户端

2.委托生成器 包含yield from表达式生成器函数

作用在子生成器和调用方之间生成建立一个双向通道

调用方可以通过send函数直接发送给子生成器 而子生成器的值也可以直接返回给调用方

3.子生成器 yiled from后面的生成器函数

python中协程与函数的区别_python协程和异步IO相关推荐

  1. python中协程与函数的区别_python 协程与go协程的区别

    进程.线程和协程 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定义: 操作系统能够进行运算调度的最小单位.它被包含在进 ...

  2. python中的方法和函数的区别_python中函数与方法的区别?

    Python中函数不是方法,主要有以下区别: 首先,从分类的角度来分析二者的区别 (1)函数的分类: 内置函数:python内嵌的一些函数. 匿名函数:一行代码实现一个函数功能. 递归函数:自己调用自 ...

  3. python中的方法和函数的区别_Python中函数和方法的区别

    在Python中函数和方法是有区别的. 区别一所处的位置:函数是直接写文件中而不是class中,方法是只能写在class中. 区别二定义的方式: 1.函数定义的方式 def关键字  然后接函数名 再是 ...

  4. Python中str()与repr()函数的区别——repr() 的输出追求明确性,除了对象内容,还需要展示出对象的数据类型信息,适合开发和调试阶段使用...

    Python中str()与repr()函数的区别 from:https://www.jianshu.com/p/2a41315ca47e 在 Python 中要将某一类型的变量或者常量转换为字符串对象 ...

  5. 【Python】Python中str()和repr()函数的区别

    作用 在 Python 中要将某一类型的变量或者常量转换为字符串对象通常有两种方法,即 str() 或者 repr() . 区别与使用 参考文章:Python 中 str() 和 repr() 函数的 ...

  6. python中的return和print的区别_python中return和print的区别(详细)

    Huskiesir python最近正在研究.今天,我面临一个问题,那就是,返回和印刷的区别.双方都能输出结果.的区别是什么?闲话少说,看下面的例子.# Code1: def break_words( ...

  7. python中元祖 字典 列表的区别_Python中元祖,列表,字典的区别

    原博文 2016-08-16 15:25 − Python中有3种內建的数据结构:列表.元祖和字典: 1.列表 list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个序列的项目. 列表中的 ...

  8. python中的内置函数怎么学_python内部函数学习(九)

    python提供了很多的内置函数,这些内置的函数在某些情况下,可以起到很大的作用,而不需要专门去 写函数实现XX功能,直接使用内置函数就可以实现,下面分别来学习内置函数的使用和案例代码. 1.abs( ...

  9. python中如何查一个函数的用法_Python常见内置函数用法(三)

    本文作者:孙雪丽 文字编辑:周聪聪 技术总编:张学人重大通知!!!2019年6月22日至24日在河南郑州举行Stata编程技术特别训练营,招生工作已经圆满结束.另外爬虫俱乐部将于2019年7月5日至7 ...

最新文章

  1. 别再说你不会 ElasticSearch 调优了,都给你整理好了
  2. 外包网络推广公司浅析网站如何通过修改网站标题来提升排名?
  3. 初步了解Linux内核中断初始化
  4. OA选型 寻找应用中的个性
  5. [css] padding会影响到元素的大小,那不想让它影响到元素的宽度应该怎么办?
  6. 项目管理工具project软件学习(一) - 项目信息设置
  7. 今日头条反省整改;微信QQ封杀短视频;雷军10亿赌约将见分晓| CSDN极客头条
  8. 搭建 zookeeper 和搭建dubbo监控中心
  9. Java之数组(下)
  10. 最小值最大化问题(贪心系列)
  11. java 读取读取配置文件
  12. python-一些文件相关的操作
  13. 如何通过SEO思维收割各大平台的流量?
  14. java的初始化和赋值的区别_Java的赋值与初始化
  15. 【OpenSource】开源管理平台BlackDuck简介
  16. windows 2008系统防火墙无法启动提示 错误1068:依赖服务或组无法启动
  17. PN532和控制器之间的交互
  18. mycat中间件(四)mycat目录结构文件及作用
  19. E. Selling Souvenirs
  20. 集成SpringSecurity和Oauth2的授权码认证

热门文章

  1. ueditor 后端配置项没有正常加载,上传插件不能正常使用 UTF8 PHP
  2. css 实现居中的五种方式
  3. ZBrush中的Clip剪切笔刷怎么快速运用
  4. Python3.x爬虫教程:爬网页、爬图片、自己主动登录
  5. hdu 2883 kebab 网络流
  6. Leetcode: Binary Tree Inorder Traversal
  7. Vim 还是 Emacs
  8. VB6.0中,DTPicker日期、时间控件不允许为空时,采用文本框与日期、时间控件相互替换赋值(解决方案)
  9. 【白皮书分享】2021内容营销白皮书.pdf(附下载链接)
  10. 【报告分享】2021年中国人工智能与教育融合应用报告.pdf(附下载链接)