协程
协程:也叫做微线程,是完成多任务的另外一种方式,只不过比线程,进程占用的资源都要更小,在不开辟线程的情况下,可以创建多个协程
1.用yield创建一个协程
1.用yield创建一个协程
import time def work1(): while True: print("----work1---") yield time.sleep(0.5) def work2(): while True: print("----work2---") yield time.sleep(0.5) def main(): w1 = work1() w2 = work2() while True: next(w1) next(w2) if __name__ == "__main__": main()2.为了更好的完成多任务,python中的greenlet模块对其进行了封装import greenlet import time # 任务1 def test1(): for i in range(10): print("work1------") time.sleep(0.5) # 切换到任务2中执行任务 g2.switch() # 任务2 def test2(): for i in range(10): print("work2------") time.sleep(0.5) # 切换到任务1中执行任务 g1.switch() g1 = greenlet.greenlet(test1) g2 = greenlet.greenlet(test2) g1.switch()3.greenlet需要人工去切换到协程,太麻烦,而gevent可以实现自动切换到协程的这波操作,不在需要人工去切换, 功能比yield和greenlet更加强大。
import gevent def test1(): for i in range(10): print("----------test1-------") gevent.sleep(0.5) def test2(): for i in range(10): print("-----test2----") gevent.sleep(0.5) g1 = gevent.spawn(test1) g2 = gevent.spawn(test2) g1.join() g2.join()4.用协程实现图片下载import gevent import urllib.request from gevent import monkey # 打补丁,让gevent能够识别网络延时请求 monkey.patch_all() # 下载图片任务 def dow(url, mburl): try: # 根据图片地址获取图片资源 re = urllib.request.urlopen(url) # 创建或者打开文件写入数据 with open(mburl, "wb") as f: while True: # 一二进制的格式读取图片资源 rea = re.read(1024) if rea: #写入数据 f.write(rea) else: break except Exception as e: print("图片下载不成功") else: print("图片%s下载成功"%mburl) if __name__ == '__main__': # 准备图片地址 url1 = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=439045155,3387317936&fm=27&gp=0.jpg" url2 = 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=4003405131,3156073711&fm=27&gp=0.jpg' url3 = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2067356572,2308444715&fm=27&gp=0.jpg" # 创建 协程 g1 = gevent.spawn(dow, url1, "1.jpg") g2 = gevent.spawn(dow, url2, "2.jpg") g3 = gevent.spawn(dow, url3, "3.jpg") # 等所有的协程结束完成之后再退出程序 gevent.joinall([g1, g2, g3])