操作系统OS,Python - 协程(Coroutine)
留坑
参考:
值得注意的点:
- Python对协程的支持是通过generator实现的。
- Python中,generator的send和throw方法使得generator很像一个协程(coroutine), 但是generator只是一个半协程(semicoroutines),python doc是这样描述的:“All of this makes generator functions quite similar to coroutines; they yield multiple times, they have more than one entry point and their execution can be suspended. The only difference is that a generator function cannot control where should the execution continue after it yields; the control is always transferred to the generator’s caller.
- 一个线程可以多个协程,一个进程也可以单独拥有多个协程,这样python中则能使用多核CPU。(多进程+协程)
- greenlet是真正的协程
- Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。
例子1. 用协程实现生产者,消费者模型
"""
1. 用协程实现消费者生产者模型
2. Python对协程的支持是通过generator实现的
3. 有yield的话,就是generator
4. 整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。
"""
def consumer():
r = ''
while True:
# n为send过来的值
# yield类似于断点,有两个作用。
# 1. 生成值
# 2. 在这里断点,交出控制权。切换到另外一个协程
n = yield r
if not n:
return
print('[CONSUMER] Consuming %s...' % n)
r = '200 OK'
def produce(c):
#start generator with None
c.send(None)
n = 0
while n < 5:
n = n + 1
print('[PRODUCER] Producing %s...' % n)
#启动生成器,并附带一个值,r接收yield生成的值
r = c.send(n)
print('[PRODUCER] Consumer return: %s' % r)
c.close()
c = consumer()
produce(c)
例子2. 遇到IO阻塞时自动切换任务,based on gevent,greenlet,monkey
from gevent import monkey; monkey.patch_all()
import gevent
from urllib.request import urlopen
def f(url):
print('GET: %s' % url)
resp = urlopen(url)
data = resp.read()
print('%d bytes received from %s.' % (len(data), url))
gevent.joinall([
gevent.spawn(f, 'https://www.python.org/'),
gevent.spawn(f, 'https://www.yahoo.com/'),
gevent.spawn(f, 'https://www.baidu.com/'),
])
例子3. 单线程下实现多socket并发,based on gevent
server.py
import sys
import socket
import time
import gevent
from gevent import socket,monkey
monkey.patch_all()
def server(port):
s = socket.socket()
s.bind(('0.0.0.0', port))
s.listen(500)
while True:
cli, addr = s.accept()
gevent.spawn(handle_request, cli)
def handle_request(conn):
try:
while True:
data = conn.recv(1024)
print("recv:", data)
conn.send(data + ' [server]'.encode('utf-8'))
if not data:
conn.shutdown(socket.SHUT_WR)
except Exception as ex:
print(ex)
finally:
conn.close()
if __name__ == '__main__':
server(8006)
client.py
import socket
import threading
def sock_conn():
client = socket.socket()
client.connect(("localhost",8006))
count = 0
while True:
#msg = input(">>:").strip()
#if len(msg) == 0:continue
#从客户端收到的数据
client.send( ("hello %s" %count).encode("utf-8"))
#从服务器端收到的数据
data = client.recv(1024)
print("[%s]recv from server:" % threading.get_ident(),data.decode()) #结果
count +=1
client.close()
for i in range(100):
t = threading.Thread(target=sock_conn)
t.start()
操作系统OS,Python - 协程(Coroutine)的更多相关文章
- Python 协程 (Coroutine)
协程 (Coroutine) 什么是协程 协程(微线程)是比线程更轻量化的存在,像一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程 最重要的是,协程不是被操作系统内核所管理,而完全是由程序所控 ...
- Python并发编程协程(Coroutine)之Gevent
Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译 ...
- Python之协程(coroutine)
Python之协程(coroutine) 标签(空格分隔): Python进阶 coroutine和generator的区别 generator是数据的产生者.即它pull data 通过 itera ...
- python协程(yield、asyncio标准库、gevent第三方)、异步的实现
引言 同步:不同程序单元为了完成某个任务,在执行过程中需靠某种通信方式以协调一致,称这些程序单元是同步执行的. 例如购物系统中更新商品库存,需要用"行锁"作为通信信号,让不同的更新 ...
- 5分钟完全掌握Python协程
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 1. 协程相关的概念 1.1 进程和线程 进程(Process)是应用程序启动的实例,拥有代码.数据 ...
- (zt)Lua的多任务机制——协程(coroutine)
原帖:http://blog.csdn.net/soloist/article/details/329381 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上 ...
- 协程coroutine
协程(coroutine)顾名思义就是“协作的例程”(co-operative routines).跟具有操作系统概念的线程不一样,协程是在用户空间利用程序语言的语法语义就能实现逻辑上类似多任务的编程 ...
- Lua的多任务机制——协程(coroutine)
并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上有这么两种多任务技术,一种是抢占式多任务(preemptive multitasking),它让操作系统来决定 ...
- 再议Python协程——从yield到asyncio
协程,英文名Coroutine.前面介绍Python的多线程,以及用多线程实现并发(参见这篇文章[浅析Python多线程]),今天介绍的协程也是常用的并发手段.本篇主要内容包含:协程的基本概念.协程库 ...
随机推荐
- Eugeny and Array(思维)
Eugeny has array a = a1, a2, ..., an, consisting of n integers. Each integer ai equals to -1, or to ...
- shell脚本编程学习笔记(二)linux服务器启动流程
一.linux服务器启动流程 1.bios找到磁盘上的mbr主引导扇区 2.进入grub洁面选择相应的启动内核 3.读取kernel内核文件-/boot/vmlinuz-* 4.读取init的镜像文件 ...
- bootstrap的网格控制
<div class="container-fluid row m-0 p-0"> <div class="col-2 border"> ...
- linux日常运维工作
Linux的使用环境也日趋成熟,各种开源产品络绎不绝,大有百花齐放的盛景,那么当Linux落地企业,回归工作时,我们还要面对这Linux运维方面的诸多问题,今天我们特意组织一场有关Linux 在企业运 ...
- ‘\0’的ASCII码
1.'\0'的ASCII码为0 2.用串口发送字符串时,可以通过'\0'判断字符串是否结束,但发送数字数组的时候不能通过'\0'判断数组是否结束,因为数字0与'\0'的ASCII码值相同.
- Jmeter中cookie自动存储
1,新建一个测试计划,然后添加一个"HTTP Cookie 管理器"(用来存储cookie)2,新建一个线程组,添加一个Sampler-->“HTTP 请求”(用来登录用的) ...
- wordpress Error establishing a database connection问题
最近这场大雨,快把帝都给淹了,我也快被这不定向问题折磨疯了,本来把项目放在A服务器,nginx ,php7,mysql,然后换到了B服务器,环境一模一样,结果呢,传上去就出现了 哎,话说我的配置也没啥 ...
- Python(四)生成器 和 杨辉三角
学习链接: http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143177992 ...
- 正则去掉 html标签
var htmlStr='<p class="cjk" style="margin-bottom: 0cm; line-height: 16px;"> ...
- make工具简介
在Linux C/C++的开发过程中,当源代码文件较少时,我们可以手动使用gcc或g++进行编译链接,但是当源代码文件较多且依赖变得复杂时,我们就需要一种简单好用的工具来帮助我们管理.于是,make应 ...