zoukankan      html  css  js  c++  java
  • 并发编程——协程(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
  • 相关阅读:
    python 垃圾回收机制
    @property 取代getter setter方法
    ==值相等 is同一性
    循环获取文件名,拼接路径打印
    python 闭包
    python生成器
    hadoop集群环境搭建之zookeeper集群的安装部署
    hadoop集群环境搭建之安装配置hadoop集群
    hadoop集群环境搭建准备工作
    linux下安装jdk
  • 原文地址:https://www.cnblogs.com/GraceZ/p/8428655.html
Copyright © 2011-2022 走看看