协程:
可以暂停的函数,并在暂停处传值
为了解决:
1.回调模式编码复杂度高
2.同步编程的并性性不高
3.多线程编程需要线程间同步, lock
1.采用同步的方式去编写异步的代码
2.使用单线程去切换任务:
1.纯种是由操作系统切换的, 单线程切换意味着我们需要程序员自己去调度任务
2.不再需要锁,并发性高,如果单线程内切换函数,性能远高于线程切换, 并发性更高
生成器send, close, throw方法
send
def get_html():
html = yield "http://www.baidu.com"
print(html)
yield 2
yield 3
return "something"
if __name__ == "__main__":
gen = get_html()
url = next(gen) # url 会被赋值成为"http://www.baidu.com“
print(url)
var = 'dylan'
gen.send(var) # 相当于把主线程中的var变量值传给生成器中的html局部变量,并打印出来,如果用print打印这一条命令,会返回2,即到下一个yield命令的值
close
def get_html():
yield "http://www.baidu.com"
yield 2
yield 3
return "something"
if __name__ == "__main__":
gen = get_html()
url = next(gen)
gen.close()
next(gen) # 假如没有这一行命令,以上代码不会报出异常。如果有这一行命令,则上一条命令gen.close()会抛出异常,因为该命令已经把生成器停止了。如果在生成器内捕获异常,会导致主线程剩下的代码无法执行(即使与生成器无关的代码也不会执行)
def get_html():
try:
yield "http://www.baidu.com"
except GeneratorExit:
pass
yield 2
yield 3
return "something"
if __name__ == "__main__":
gen = get_html()
url = next(gen)
gen.close() # 抛出异常
print('dylan') # 不会执行
throw
def get_html():
yield "http://www.baidu.com"
yield 2
yield 3
return "something"
if __name__ == "__main__":
gen = get_html()
url = next(gen)
gen.throw(Exception, 'download error') # 传入异常,会在上一条yield语句抛出异常。如果print这行代码,即print(gen.throw(Exception, 'download error')时会返回下一条yield的结果,本例即为2。
print('dylan')