目录

1、协程的优势:

2、生产者消费者协程模型

3、协程gevent实例


1、协程的优势:

  • 协程的执行效率高。因为子程序切换不是线程切换,而是由程序自身控制。因此,没有线程切换的开销,和多线程相比,线程数量越多,相同数量的协程体现出的优势越明显
  • 不需要多线程的锁机制。由于只有一个线程,也不存在同时写变量的冲突,在协程中控制共享资源不需要加锁,只需要判断数据的状态,所以执行效率远高于线程 ,对于多核CPU可以使用多进程+协程来尽可能高效率地利用CPU。
  • 通俗易懂的回答:让原来要使用异步+回调方式写的非人类代码,可以用看似同步的方式写出来...

2、生产者消费者协程模型

 (1)yield方式

import timedef consumer():r = ''while True:n = yield rif not n:returnprint('[消费者] <--- Consuming %s...' % n)time.sleep(1)r = 'ok'def producer(c):next(c)n = 0while n < 5:n = n + 1print('[生产者] ---> Producing %s...' % n)# 和next有同样的同能,可以触发函数到下一个yield,# 区别于next的是可以像yield的左边的变量传值,例如上面yield左边的nc_ret = c.send(n)  print('[生产者] Consumer return %s' % c_ret)c.close()if __name__ == '__main__':c = consumer()producer(c)

结果如下:

[生产者] ---> Producing 1...
[消费者] <--- Consuming 1...
[生产者] Consumer return ok
[生产者] ---> Producing 2...
[消费者] <--- Consuming 2...
[生产者] Consumer return ok
[生产者] ---> Producing 3...
[消费者] <--- Consuming 3...
[生产者] Consumer return ok
[生产者] ---> Producing 4...
[消费者] <--- Consuming 4...
[生产者] Consumer return ok
[生产者] ---> Producing 5...
[消费者] <--- Consuming 5...
[生产者] Consumer return ok

使用yield手动实现协程是比较麻烦的,Python提供了greenlet和gevent模块用来实现协程。

(2)greenlet方式

from greenlet import greenlet
import timedef A():while 1:print('-------A-------')time.sleep(0.5)g2.switch()def B():while 1:print('-------B-------')time.sleep(0.5)g1.switch()g1 = greenlet(A)  #创建协程g1
g2 = greenlet(B)g1.switch()  #跳转至协程g1

结果如下:

-------A-------
-------B-------
-------A-------
-------B-------
-------A-------

(3)gevent方式

gevent每次遇到io操作,需要耗时等待时,会自动跳到下一个协程继续执行。

import geventdef A():while 1:print('-------A-------')gevent.sleep(1) #用来模拟一个耗时操作,注意不是time模块中的sleepdef B():while 1:print('-------B-------')gevent.sleep(0.5)  #每当碰到耗时操作,会自动跳转至其他协程g1 = gevent.spawn(A) # 创建一个协程
g2 = gevent.spawn(B)
g1.join()  #等待协程执行结束
g2.join()

结果如下:

-------A-------
-------B-------
-------B-------
-------A-------
-------B-------
-------B-------
-------A-------
-------B-------
-------B-------

3、协程gevent实例

利用gevent完成协程方式的回显服务器


import gevent
from gevent import monkey,socketmonkey.patch_all()   #有IO才做时需要这一句s = socket.socket(2,1)  #用的都是gevent模块中的socket,但用法一样
s.setsockopt(1,2,1)
s.bind(('',8080))
s.listen(1024)def func_accept():while 1:cs,userinfo = s.accept()print('来了一个客户'+str(userinfo))g = gevent.spawn(func_recv,cs)  #每当有用户连接,增加一条协程def func_recv(cs):while 1:recv_data = cs.recv(1024)print(recv_data)  #程谁堵塞了,便会跳转至其他协程if len(recv_data) > 0:cs.send(recv_data)else:cs.close()breakg1 = gevent.spawn(func_accept)
g1.join()

协程(Python)相关推荐

  1. python3异步编程_协程 Python异步编程(asyncio)

    协程(Coroutine) 也可以被称为微线程,是一种用户态内的上下文切换技术.简而言之,其实就是通过一个线程实现代码块相互切换执行. 直接上代码,例如: 同步编程 import time def f ...

  2. python协程库_python中协程的详解(附示例)

    本篇文章给大家带来的内容是关于python中协程的详解(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 协程,又称微线程,纤程.英文名Coroutine 协程看上去也是子程序 ...

  3. Python与Golang协程异同

    背景知识 这里先给出一些常用的知识点简要说明,以便理解后面的文章内容. 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定 ...

  4. Python—进程、线程、协程

    一.线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 方法: ...

  5. python coroutine,go routine对比--理解多线程、协程

    1. 线程实现模型 线程的实现模型主要有3种:内核级线程模型.用户级线程模型和混合型线程模型.它们之间最大的区别在于线程与内核调度实体KSE(Kernel Scheduling Entity)之间的对 ...

  6. 从yield 到yield from再到python协程

    yield 关键字 def fib():a, b = 0, 1while 1:yield ba, b = b, a+b yield 是在:PEP 255 -- Simple Generators 这个 ...

  7. 线程和协程详解-python

    1.前言 关于基本概念部分这里不再详述,可以参考之前的文章或者自行查阅相关文章. 由于python中线程的创建.属性和方法和进程很相似,这里也不再讲解. 这里重点讲解下多线程访问共享数据的相关问题. ...

  8. Python之路 34:并发与并行、锁(GIL、同步锁、死锁与递归锁)、信号量、线程队列、生消模型、进程(基础使用、进程通信、进程池、回调函数)、协程

    内容: 同步锁 死锁.递归锁 信号量和同步对象(暂时了解即可) 队列------生产者和消费者模型 进程(基础使用.进程通信.进程池.回调函数) 协程 一.并发并行与同步异步的概念 1.1.并发和并行 ...

  9. python 协程、进程、线程_Python的进程、线程和协程 · Donzy’s Blogs

    0.前言 在计算机技术领域,吞吐量(throughput)是计算机在指定的一段时间内完成编程技术如何影响.本文主要讨论Python的多进程.多线程及协程等编程技术在不同场景下对系统吞吐量的影响. 1. ...

  10. 【Python】【入门篇】十二、Python中协程

    目录 十二.Python中协程 12.1 协程的定义 12.2 协程 12.3 协程池 12.4 总结 十二.Python中协程 12.1 协程的定义 协程(Coroutine):是一种比线程更加轻量 ...

最新文章

  1. 微信小程序---导航(navigator)
  2. C#virtual和abstract的区别
  3. js实现给a href= href赋值
  4. linux中使用ssh或scp时如何跳过RSA key fingerprint输入yes/no
  5. Linux C获取文件属性
  6. 以后台服务的形式启动nodejs应用
  7. Go语言常用的并发模式(上)
  8. 跨域通信——多窗口通信
  9. .msi文件安装出现2503、2502错误
  10. Unity3D shader简介
  11. NC65 通过编码规则生成物料编码
  12. MP4Box获取MP4媒体文件的播放时长
  13. leetcode707.设计链表(Python实现)
  14. 实战四:Kaggle自行车租赁预测比赛
  15. 凑微分公式_高等数学–求积分的一些方法(IV 凑微分法)
  16. 使用Java模拟登录
  17. Java IO有这么难吗?
  18. 从0开始学习开发微信小程序(熟悉微信开发者工具页面,简单修改、添加一些内容)
  19. 一文看懂:性能监控神器JavaMelody
  20. k8s 安装nfs_kubernetes挂载nfs报错 | 运维笔记

热门文章

  1. jenkins配置记录(1)--添加用户权限
  2. 使用truss、strace或ltrace诊断软件的疑难杂症
  3. 计数显示器c语言程序,51单片机计数显示器Proteus仿真程序
  4. oracle resetlog与noresetlog的作用(转载)
  5. PHP数组的使用方法小结
  6. linux vim 粘贴 没有保持原来的格式,linux中的剪贴板用法,实现vim中原格式粘贴...
  7. java list 之详解_java集合(二)List集合之ArrayList详解
  8. swagger : Could not resolve reference because of: Could not resolve pointer
  9. idea中push到github或gitee过程中的常见错误记录
  10. 用java画网状图_如何在背景中绘制一个带网格线的漂亮条形图?