协程和I/O模型
1、协程:
单线程实现并发
在应用程序里控制多个任务的切换+保存状态
优点:
应用程序级别速度要远远高于操作系统的切换
缺点:
多个任务一旦有一个阻塞没有切换,整个线程都阻塞在原地
该线程内的其他的任务都不能执行了 一旦引入协程,就需要检测单线程下所有的IO行为,
实现遇到IO就切换,少一个都不行,因为一旦一个任务阻塞了,整个线程就阻塞了,
其他的任务即便是可以计算,但是也无法运行了 2、协程的目的:
想要在单线程下实现并发
并发指的是多个任务看起来是同时运行的
并发=切换+保存状态
from gevent import monkey,spawn;monkey.patch_all()
from threading import current_thread
import time
# 实现了单线程下的并发,遇到i/O就切换
def eat():
print('%s eat 1' %current_thread().name)
time.sleep(3)
print('%s eat 2' %current_thread().name) def play():
print('%s play 1' %current_thread().name)
time.sleep(1)
print('%s play 2' %current_thread().name) start = time.time()
g1=spawn(eat,) # 创建一个协程对象
g2=spawn(play,) print(current_thread().name)
g1.join() # 也有join方法
g2.join() stop = time.time()
print(stop-start) # MainThread
# DummyThread-1 eat 1 虚假线程
# DummyThread-2 play 1
# DummyThread-2 play 2
# DummyThread-1 eat 2
# 3.003624439239502
单线程下的并发
并发的套接字通信
from gevent import spawn,monkey;monkey.patch_all()
from socket import *
from threading import Thread def talk(conn):
while True:
try:
data=conn.recv(1024)
if len(data) == 0:break
conn.send(data.upper())
except ConnectionResetError:
break
conn.close() def server(ip,port,backlog=5):
server = socket(AF_INET, SOCK_STREAM)
server.bind((ip, port))
server.listen(backlog) print('starting...')
while True:
conn, addr = server.accept()
spawn(talk, conn,) # 指定执行的任务,后面的conn是传入的参数 if __name__ == '__main__':
g=spawn(server,'127.0.0.1',8080) # 执行server
g.join()
服务端
from threading import Thread,current_thread
from socket import *
import os def task():
client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8080)) while True:
msg='%s say hello' %current_thread().name
client.send(msg.encode('utf-8'))
data=client.recv(1024)
print(data.decode('utf-8')) if __name__ == '__main__':
for i in range(500):
t=Thread(target=task)
t.start()
客户端
网络IO:
recvfrom:
wait data:等待客户端产生数据——》客户端OS--》网络--》服务端操作系统缓存
copy data:由本地操作系统缓存中的数据拷贝到应用程序的内存中 send:
copy data # conn.recv(1024) ==>OS
非阻塞I/O模型
from socket import *
import time server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1',8080))
server.listen(5)
server.setblocking(False) conn_l=[]
while True:
try:
print('总连接数[%s]' % len(conn_l))
conn,addr=server.accept()
conn_l.append(conn)
except BlockingIOError:
del_l=[]
for conn in conn_l:
try:
data=conn.recv(1024)
if len(data) == 0:
del_l.append(conn)
continue
conn.send(data.upper())
except BlockingIOError:
pass
except ConnectionResetError:
del_l.append(conn) for conn in del_l:
conn_l.remove(conn)
服务端
from socket import *
import os client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8080)) while True:
msg='%s say hello' %os.getpid()
client.send(msg.encode('utf-8'))
data=client.recv(1024)
print(data.decode('utf-8'))
客户端
协程和I/O模型的更多相关文章
- Python开发——15.协程与I/O模型
一.协程(Coroutine) 1.知识背景 协程又称微线程,是一种用户态的轻量级线程.子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完 ...
- python 协程、I/O模型
一.引子 (超哥协程) 并发本质:保存状态+切换 cpu正在运行一个任务,转而执行另一个任务的情概况:1.是该任务发生了阻塞:2.该任务计算的时间过长或有一个优先级更高的程序替代了它. 协程本质上就是 ...
- Python进阶(5)_进程与线程之协程、I/O模型
三.协程 3.1协程概念 协程:又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存 ...
- GIL全局解释器锁、协程运用、IO模型
GIL全局解释器锁 一.什么是GIL 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就好比C是一套语言(语法)标准,但是可以用不 ...
- 【Python】协程实现生产者消费者模型
协程的实现为协作式而非抢占式的,这是和进程线程的最大区别.在Python中,利用yield和send可以很容易实现协程. 首先复习下生成器. 如果一个函数使用了yield语句,那么它就是一个生成器函数 ...
- 7.24python协程(2)和IO模型
2018-7-24 08:50:29 异步IO模型 epoll 机制 linux 给每个监听对象绑定回调函数,当要读的对象来了时候,回调函数直接被执行,然后通知用户,效率非常高! python无法 ...
- 图解协程调度模型-GMP模型
现在无论是客户端.服务端或web开发都会涉及到多线程的概念.那么大家也知道,线程是操作系统能够进行运算调度的最小单位,同一个进程中的多个线程都共享这个进程的全部系统资源. 线程 三个基本概念 内核线程 ...
- 基于ASIO的协程与网络编程
协程 协程,即协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态.协程可以在运行期间的某个点上暂停执行,并在恢复运行时从暂停的点上继续执行. 协程 ...
- Python实现基于协程的异步爬虫
一.课程介绍 1. 课程来源 本课程核心部分来自<500 lines or less>项目,作者是来自 MongoDB 的工程师 A. Jesse Jiryu Davis 与 Python ...
随机推荐
- Quartz -第一篇-入门
学习地址:https://www.imooc.com/learn/846 官网:www.quartz-scheduler.org 特点:分布式+集群 设计模式: 工厂模式 builder模式 组件模式 ...
- HDU 5627Clarke and MST
Clarke and MST Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- Java 字符串比较小知识
使用 String.compareTo 方法: compareTo() 的返回值是int, 它是先比较对应字符的大小(ASCII码顺序). 1.如果字符串相等,返回值0. 2.如果第一个字符和参数的第 ...
- cassandra在服务端像leveldb一样进行插入初试成功
经过研究,决定在 cql3/QueryProcessor.java 里面下手. 这里有两个函数,第一个是 public ResultMessage process(String queryString ...
- git push不成功 insufficient permission for adding an object to repository database
这常见于多用户. 1. 确保所有用户在同一个组: 2. 确保所有文件被组可读写. 当多个用户各自进行了push操作后,object目录下的文件可能各自属于各个用户.
- position属性中的绝对定位和相对定位
absolute(绝对定位):1.如果没有父级DIV,则会根据浏览器原始点去定位,而且跟他相邻的DIV会忽略它,定位后则可用TRBL(top,right,bottom,left)去布局.注意:TRBL ...
- 使用pngcrush压缩png图片
写在前面: Pngcrush是一个优化的PNG(便携式网络图形)文件.它可以运行在MSDOS窗口中一个命令行,或从UNIX或LINUX命令行.其主要目的是为了 减少PNG IDAT数据 ...
- liunx操作系统安装<一>
一:磁盘分区类型(1)主分区(最多四个主分区,比如window系统的C盘,D盘)(2)扩展分区,逻辑分区(为了能让磁盘多分出几个区域而存在)(3)交换分区(虚拟内存,当物理内存不足时候,作为应急存在)
- 深入理解js里面的this
闲聊两句(可以忽略): 毕业有半年了,时间还过得真快,不过还好,感觉自己相对于刚毕业那会确实成长了很多:好久没有打游戏了(自己决心要戒掉的),消磨时光的时候就看看电影或者追追电视剧,再无聊就洗洗衣服. ...
- 斯坦福CS231n—深度学习与计算机视觉----学习笔记 课时5
课时5 数据驱动的图像分类方式:K最邻近与线性分类器(下) 在参数化方法中,我们要做的是构造一个函数,输入一张图片,对每一类输出一个数值.对任意一张图片,我们会计算出它到底属于哪一类.这些参数有时候也 ...