协程(Python)
目录
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)相关推荐
- python3异步编程_协程 Python异步编程(asyncio)
协程(Coroutine) 也可以被称为微线程,是一种用户态内的上下文切换技术.简而言之,其实就是通过一个线程实现代码块相互切换执行. 直接上代码,例如: 同步编程 import time def f ...
- python协程库_python中协程的详解(附示例)
本篇文章给大家带来的内容是关于python中协程的详解(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 协程,又称微线程,纤程.英文名Coroutine 协程看上去也是子程序 ...
- Python与Golang协程异同
背景知识 这里先给出一些常用的知识点简要说明,以便理解后面的文章内容. 进程的定义: 进程,是计算机中已运行程序的实体.程序本身只是指令.数据及其组织形式的描述,进程才是程序的真正运行实例. 线程的定 ...
- Python—进程、线程、协程
一.线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 方法: ...
- python coroutine,go routine对比--理解多线程、协程
1. 线程实现模型 线程的实现模型主要有3种:内核级线程模型.用户级线程模型和混合型线程模型.它们之间最大的区别在于线程与内核调度实体KSE(Kernel Scheduling Entity)之间的对 ...
- 从yield 到yield from再到python协程
yield 关键字 def fib():a, b = 0, 1while 1:yield ba, b = b, a+b yield 是在:PEP 255 -- Simple Generators 这个 ...
- 线程和协程详解-python
1.前言 关于基本概念部分这里不再详述,可以参考之前的文章或者自行查阅相关文章. 由于python中线程的创建.属性和方法和进程很相似,这里也不再讲解. 这里重点讲解下多线程访问共享数据的相关问题. ...
- Python之路 34:并发与并行、锁(GIL、同步锁、死锁与递归锁)、信号量、线程队列、生消模型、进程(基础使用、进程通信、进程池、回调函数)、协程
内容: 同步锁 死锁.递归锁 信号量和同步对象(暂时了解即可) 队列------生产者和消费者模型 进程(基础使用.进程通信.进程池.回调函数) 协程 一.并发并行与同步异步的概念 1.1.并发和并行 ...
- python 协程、进程、线程_Python的进程、线程和协程 · Donzy’s Blogs
0.前言 在计算机技术领域,吞吐量(throughput)是计算机在指定的一段时间内完成编程技术如何影响.本文主要讨论Python的多进程.多线程及协程等编程技术在不同场景下对系统吞吐量的影响. 1. ...
- 【Python】【入门篇】十二、Python中协程
目录 十二.Python中协程 12.1 协程的定义 12.2 协程 12.3 协程池 12.4 总结 十二.Python中协程 12.1 协程的定义 协程(Coroutine):是一种比线程更加轻量 ...
最新文章
- 微信小程序---导航(navigator)
- C#virtual和abstract的区别
- js实现给a href= href赋值
- linux中使用ssh或scp时如何跳过RSA key fingerprint输入yes/no
- Linux C获取文件属性
- 以后台服务的形式启动nodejs应用
- Go语言常用的并发模式(上)
- 跨域通信——多窗口通信
- .msi文件安装出现2503、2502错误
- Unity3D shader简介
- NC65 通过编码规则生成物料编码
- MP4Box获取MP4媒体文件的播放时长
- leetcode707.设计链表(Python实现)
- 实战四:Kaggle自行车租赁预测比赛
- 凑微分公式_高等数学–求积分的一些方法(IV 凑微分法)
- 使用Java模拟登录
- Java IO有这么难吗?
- 从0开始学习开发微信小程序(熟悉微信开发者工具页面,简单修改、添加一些内容)
- 一文看懂:性能监控神器JavaMelody
- k8s 安装nfs_kubernetes挂载nfs报错 | 运维笔记
热门文章
- jenkins配置记录(1)--添加用户权限
- 使用truss、strace或ltrace诊断软件的疑难杂症
- 计数显示器c语言程序,51单片机计数显示器Proteus仿真程序
- oracle resetlog与noresetlog的作用(转载)
- PHP数组的使用方法小结
- linux vim 粘贴 没有保持原来的格式,linux中的剪贴板用法,实现vim中原格式粘贴...
- java list 之详解_java集合(二)List集合之ArrayList详解
- swagger : Could not resolve reference because of: Could not resolve pointer
- idea中push到github或gitee过程中的常见错误记录
- 用java画网状图_如何在背景中绘制一个带网格线的漂亮条形图?