并发编程——协程(5)

1.协程

  • 协程:是单线程下的并发,又称微线程;协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。
  • 优点
    • 1.协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级
    • 2、单线程内就可以实现并发的效果,最大限度地利用CPU
  • 缺点:
    • 1.协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程
    • 协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程
  • 特点总结:
    • 1.必须在只有一个单线程里实现并发
    • 2.修改共享数据不需加锁
    • 3.用户程序里自己保存多个控制流的上下文栈
    • 4.一个协程遇到IO操作自动切换到其他协程(如何实现检测IO,yield、greenlet都无法实现,就用到了gevent模块(select机制))

2.greenlet模块

  • 优点:比generator便捷
  • 缺点:当切刀一个任务执行时如果遇到io,那就原地阻塞,仍然是没有解决遇到IO自动切换来提升效率的问题
  •  1 #-*- coding:utf-8 -*-
     2 # greenlet : 遇IO切不了
     3 from greenlet import greenlet
     4 import time
     5 def eat(name):
     6     print("%s eat 1"%name)
     7     time.sleep(3)#遇IO不切
     8     g2.switch("egon")#第一次需传参数
     9     print("%s eat 2"%name)
    10     g2.switch()
    11 def play(name):
    12     print("%s play 1"%name)
    13     g1.switch()
    14     print("%s play 2"%name)
    15 g1 = greenlet(eat)
    16 g2 = greenlet(play)
    17 g1.switch("egon")
    greenlet模块

3.gevent模块

  •  1 #
     2 # import gevent
     3 # import time
     4 # #gevent 只能切自己的IO
     5 # def eat(name):
     6 #     print("%s eat 1"%name)
     7 #     gevent.sleep(3)
     8 #     print("%s eat 2"%name)
     9 # def play(name):
    10 #     print("%s play 1"%name)
    11 #     gevent.sleep(4)
    12 #     print("%s play 2"%name)
    13 # start_time = time.time()
    14 # g1 = gevent.spawn(eat,'egon')
    15 # g2 = gevent.spawn(play,'alex')
    16 #
    17 # g1.join()
    18 # g2.join()
    19 # end_time = time.time()
    20 # print(end_time-start_time)
    21 
    22 # 解决gevent只能切自己IO的方法
    23 from gevent import monkey
    24 monkey.patch_all()
    25 import gevent
    26 import time
    27 def eat(name):
    28     print("%s eat 1"%name)
    29     # gevent.sleep(3)
    30     time.sleep(3)
    31     print("%s eat 2"%name)
    32 def play(name):
    33     print("%s play 1"%name)
    34     # gevent.sleep(4)
    35     time.sleep(4)
    36     print("%s play 2"%name)
    37 start_time = time.time()
    38 g1 = gevent.spawn(eat,'egon')
    39 g2 = gevent.spawn(play,'alex')
    40 
    41 g1.join()
    42 g2.join()
    43 # gevent.joinall()
    44 end_time = time.time()
    45 print(end_time-start_time)
    gevent

     

posted @ 2018-03-10 16:00  GraceZen  阅读(110)  评论(0编辑  收藏  举报