• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MC_Hotdog
Yeah, you're right I'm still riding that crappy bike
博客园    首页    新随笔    联系   管理    订阅  订阅

Python之协程

协程

  协程是程序员创造出来的不真实的一个东西

    协程也可以称之为微线程,就是程序员可以人为的控制代码的运行的顺序(来回切换),其实就是对线程进行分片,使起代码来回切换

 在线程中来回切换的实例

 

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import greenlet
 5 
 6 
 7 def testone():
 8     print(11)
 9     gr2.switch()
10     print(22)
11     gr2.switch()
12 
13 
14 def testtwo():
15     print(33)
16     gr1.switch()
17     print(44)
18 
19 
20 # 创建两个协程
21 gr1 = greenlet.greenlet(testone)
22 gr2 = greenlet.greenlet(testtwo)
23 
24 gr1.switch()
25 # 单纯的协程没多大用  切换肯定还是存在时间的消耗

 

协程存在的意义

  单纯的协程没多大用,就是遇到IO操作切换的时候就显得格外的牛逼,就有格局了

 

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from gevent import monkey
 5 monkey.patch_all()  # 代码中遇到IO都会自动执行greenlet的switch进行切换
 6 import requests
 7 import gevent
 8 
 9 
10 def get_page(url):
11     ret = requests.get(url)
12     print(url, ret.content.decode('utf8'))
13 
14 
15 gevent.joinall([
16     gevent.spawn(get_page, 'https://www.python.org/'),  # 协程1
17     gevent.spawn(get_page, 'https://www.yahoo.com/'),   # 2
18     gevent.spawn(get_page, 'https://github.com/'),      # 3
19 ])

 

总结:**********

1.什么是协程:
  称之为微线程,开发者控制线程执行流程,控制先执行某段代码然后再切换到另外的函数执行。协程本身是由程序员创造出的一个不真实存在的东西
2.协程可以提高并发吗?
  协程本身是无法实现并发 协程+io切换性能就能提高
3.进程 线程 协程区别?
  一个应用程序就是一块软件,一块软件中可以有多个进程,进程就是计算机分配资源的最小单元,主要用来做数据隔离,一个进程中至少存在一个线程(这个线程就是这个进程中的主线程),而线程就是CPU最小工作单元,真正用来工作的就是线程,但是呢在应用场景下:在其他语言中可能基本没咋提进程这个概念,他们基本用的线程,在python中呢有那么一说就是一般io密集型操作用多线程,计算密集型呢就用多进程,其实就是Python内部加了一把GIL锁,就是一个进程中同一时刻只允许一个线程被CPU调度,如果想利用CPU的多核优势,只能开进程,所以呢只有计算密集型才适合开进程,开多线程没用,而io密集型就要开线程,因为io操作不占CPU,程序员这个级别越来越牛逼嘛就创建了协程,这个协程本身就是不存在的东西,协程本身由程序员人为来控制代码块进行切换,本身存在没大多意义,如果协程遇到io切换了就非常牛逼了,遇到io操作就可以干其它的事情,相当于一个线程被分片了,所达到的效果就是这个线程一直没有停一直都在工作 ,这些就是这几个东西的本质上的区别,然后呢Python中协程有个greenlet模块就是可以进行代码块的切换这个模块,实现协程+io自动操作就是用的gevent这个模块,其实这个gevent这个模块也用到了greenlet这个模块,它里边有个monkey.patch_all()方法在这里就是遇到IO自动就会采用greenlet去自动的切换,gevent里边对源生的socket/select/threading/subprocess等等一些列的封装大概这三者之间的区别。想了解gevent自己看源码。

还有个简单的例子就是利用生成器关键字yield实现

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 
 5 def f1():
 6     print(11)
 7     x1 = yield 1
 8     print(x1, 22)
 9     x2 = yield 2
10     print(x2, 33)
11 
12 
13 def f2():
14     print(55)
15     yield
16     print(66)
17     yield
18     print(77)
19 
20 
21 v1 = f1()
22 v2 = f2()
23 # next(v1)
24 # v1.__next__()
25 r1 = v1.send(None)  # 11
26 print(r1)  # 1
27 r2 = v1.send(999)  # x1=999   999 22
28 print(r2)  # 2

 







 

posted @ 2019-07-23 20:43  MC_Hotdog  阅读(202)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3