协程 : gevent模块,遇到io自动切换任务
from gevent import monkey;monkey.patch_all() # 写在最上面 这样后面的所有阻塞就全部能够识别了
import gevent # 直接导入即可
from threading import current_thread
import time
def eat(name):
print('%seat1'% name)
# gevent.sleep(2)
time.sleep(2) # 加上monkey就能
print('%seat2'% name)
print(current_thread().getName())
def play(name):
print('%splay1'% name)
# gevent.sleep(2)
time.sleep(2)
print('%splay2'% name)
print(current_thread().getName())
g1 = gevent.spawn(eat,'egon') # 创建一个协程对象 spawn括号内第一个参数是函数名
g2 = gevent.spawn(play,'egon')
gevent.joinall([g1,g2]) # 将g1.join()和g2.join()合成一步写了出来
print('主')
# 结果为
# egoneat1
# egonplay1
# egoneat2
# DummyThread-1 # 假线程 虚拟线程 其实都在一个线程里面
# egonplay2
# DummyThread-2
# 主
gevent.sleep(2)模拟的是gevent可以识别的io阻塞,
而 time.sleep(2)或其他阻塞 是不能直接识别的 需要用下面一行代码打补丁 就可以识别了
from gevent import monkey;monkey.patch_all() 放在time, socket之前 或者直接将其放在文件开头.
协程是通过自己的程序实现切换 自己能够控制 只有遇到协程模块能够识别io操作的时候, 程序才会进行任务切换 实现并发效果 , 如果所有的程序都没有io操作 那么久基本属于串行执行了.
给大家看一个线程下(协程)来实现多个客户聊天
io多路复用:模型(解决问题方案)
#服务端
from socket import *
import select
server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1',8093))
server.listen(5)
# 设置为非阻塞
server.setblocking(False)
# 将初始化服务端socket对象加入监听列表 后面还要动态添加一些conn连接对象, 当accept的时候sk就有感应 , 当recv的时候conn就有动静
rlist = [server,]
rdata = {} # 存放客户端发送过来的消息
wlist = [] # 等待写对象
wdata = {} # 存放要返回客户端的消息
print('准备监听!')
count = 0 # 写着计数用的 为了看实验效果用的 , 没用
while 1:
# 开始select监听,对rlist中服务端server进行监听 , select函数阻塞进程 , 直到rlist中套接字被触发(在此例中,套接字接收到客户端发来的握手信号 , 从而变得可读 满足select函数的可读条件),被触发的(有动静的)套接字(服务器套接字)返回给了rl这个返回值里面;
rl,wl,xl = select.select(rlist,wlist,[],0.5)
print('%s 次数>>'%(count),wl)
count = count + 1
# 对rl进行循环判断是否有客户端连接进来 , 当有客户端连接进来时select将触发
for sock in rl:
# 判断当前触发的是不是socket对象, 当触发的对象是socket对象时说明有新客户端accept连接进来了
if sock == server:
# 接收客户端的连接, 获取客户端对象和客户端地址信息
conn,addr = sock.accept()
# 把新的客户端连接加入到监听列表中 当客户端连接有接受消息的时候 , select将会被触发 ,会知道这个链接有动静 , 有消息 , 那么返回geirl这个返回值列表里面
rlist.append(conn)
else:
# 由于客户端连接进来时socket接收客户端请求 , 将客户端连接加入到了监听列表中(rlist),客户端发送消息的时候这个链接将触发
# 所以判断是否是客户端连接对象触发
try:
data = sock.recv(1024)
# 没有数据的时候,将这个连接关闭掉 , 并从监听列表中移除
if not data:
sock.close()
rlist.remove(sock)
continue
print('received{0} from client{1}'.format(data.decode(),sock))
# 将接收到的客户端的消息保存下来
rdata[sock] = data.decode()
# 将客户端连接对象和这个对象接受到的消息加工成返回消息 , 并添加到wdata这个字典里面
wdata[sock] = data.upper()
# 要给这个客户端回复消息的时候, 我们将这个链接添加到wlist监听列表中
wlist.append(sock)
# 如果这个连接出错了,客户端暴力断开了(注意 , 还没有接收到客户端的消息 , 或者接收消息的过程中出错了)
except Exception:
# 关闭这个连接
sock.close()
# 在监听列表中将他删除 , 因为不管什么原因 毕竟是断开了 没必要再监听他了
rlist.remove(sock)
# 如果现在没有客户端请求连接 也没有客户端发送消息时 , 开始对发送消息的列表进行处理 , 是否需要发送消息
for sock in wl:
sock.send(wdata[sock])
wlist.remove(sock)
wdata.pop(sock)
# 将以此select监听列表中有接收数据的conn对象所接收到的消息打印一下
# for k , v in rdata.items():
# print(k,'发来的消息是',v)
# # 清空接收到的消息
#rdata.clear()
知识总结 :
1 cs架构 bs架构
2 网络通信流程:
网卡 mac地址 子网掩码 网关 dns服务器 dhcp nat(网络地址转换) 端口(表示电脑上某个应用程序) 路由器 交换机 集线器 广播 单播 广播风暴 ARP协议 路由协议
3 网络网络通信协议(**)
osi七层 应表会传网数物
tcp\ip协议 应用层 网络层 数据链路层 物理层
tcp(*****)
三次握手 客-->服--->客
四次挥手
tcp和udp区别(*****)
tcp: 面向连接 消息可靠 效率相对差 面向流的消息格式 无消息保护边界
udp:面向无连接 不可靠 效率很高 面向包的消息格式 有消息保护边界
4 socket
缓冲区:
粘包现象 : 1 连续发送小包并且间隔时间很短 就会发送两个消息合并在一起的情况 (Nagel优化算法导致的) 2 一次发送数据过大 对方一次未接收完 下次接受的时候连同第一次剩下的消息一同接受了 导致粘包
解决粘包方案 都不知道对方发送的消息长度 1 发送消息之前先发送消息长度 收到对方确认信息后再次发送消息 2 通过struct 模块 自定义报头 将消息长度打包成4个字节长度的信息 连同你要发送的数据一并发过去
打包 pack('i',长度) 长度是个整数
协程:gevent模块,遇到i/o自动切换任务 038的更多相关文章
-
python编程中的并发------协程gevent模块
任务例子:喝水.吃饭动作需要耗时1S 单任务:(耗时20s) for i in range(10): print('a正在喝水') time.sleep(1) print('a正在吃饭') time. ...
-
协程--gevent模块(单线程高并发)
先恶补一下知识点,上节回顾 上下文切换:当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行.这种 ...
-
协程gevent模块和猴子补丁
# pip 装模块 greenlet和gevent # 协程 # 与进程.线程一样也是实现并发的手段 # 创建一个线程.关闭一个线程都需要创建寄存器.栈等.需要消耗时间 # 协程本质上是一个线程 # ...
-
python 并发编程 协程 gevent模块
一 gevent模块 gevent应用场景: 单线程下,多个任务,io密集型程序 安装 pip3 install gevent Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步 ...
-
python之协程gevent模块
Gevent官网文档地址:http://www.gevent.org/contents.html 进程.线程.协程区分 我们通常所说的协程Coroutine其实是corporate routine的缩 ...
-
python 线程(其他方法,队列,线程池,协程 greenlet模块 gevent模块)
1.线程的其他方法 from threading import Thread,current_thread import time import threading def f1(n): time.s ...
-
协程----greenlet模块,gevent模块
1.协程初识,greenlet模块 2.gevent模块(需要pip安装) 一.协程初识,greenlet模块: 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线 ...
-
14 并发编程-(协程)-greenlet模块&;gevent模块
1.实现多个任务之间进行切换,yield.greenlet都没有实现检测I/O,greenlet在实现多任务切换下更简单 from greenlet import greenlet def eat(n ...
-
Python之路(第四十七篇) 协程:greenlet模块\gevent模块\asyncio模块
一.协程介绍 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 协程相比于线程,最大的区别在于 ...
随机推荐
-
孙鑫MFC学习笔记10:画图/贴图
1.SetPixel在指定点设置像素 2.虚线.点线宽度必须为1 3.CColorDialog创建颜色对话框 4.需要设置CC_RGBINIT标志才能设置颜色对话框的默认颜色 5.CC_FULLOPE ...
-
XP系统取消开机硬件检查
非正常关机后进行磁盘检查,主要用于检查磁盘错误等.非法关机后会丢失一些文件或产生一些文件错误,而硬盘自检恰恰就是来检查这些错误并对之进行必要的修复,此功能如果被关闭,不能进行必要的数据恢复,久而久之会 ...
-
js表格排序 &; 去除字符串空格
// a:列数 bool:排序升序判断参数 true false Str:支持多列 function newUnitSort(a, bool, str) { var oTable = document ...
-
UESTC 1272 Final Pan's prime numbers(乱搞)
题目链接 Description Final Pan likes prime numbers very much. One day, he want to find the super prime n ...
-
深入理解ajax系列第九篇——jQuery中的ajax
前面的话 jQuery提供了一些日常开发中需要的快捷操作,例如load.ajax.get和post等,使用jQuery开发ajax将变得极其简单.这样开发人员就可以将程序开发集中在业务和用户体验上,而 ...
-
面试题:判断连个字符串是否互为回环变位(Circular Rotaion)
题干: 如果字符串 s 中的字符循环移动任意位置之后能够得到另一个字符串 t,那么 s 就被称为 t 的回环变位(circular rotation). 例如,ACTGACG 就是 TGACG ...
-
iis / asp.net 使用 .config 和 .xml 文件的区别
由于在项目中有同学使用后缀为 .xml 的文件作为配置文件,而配置文件中有一些敏感信息被记录,如接口地址,Token,甚至还有数据库连接字符串. 以前都没想过为何微软会使用.config 的后缀在作为 ...
-
关于JavaScript中的几种匿名行数的写法
匿名函数没有实际名字,也没有指针,怎么执行滴? 其实大家可以看看小括号的意义就应该可以理解.小括号有返回值,也就是小括号内的函数或者表达式的返回值,所以说小括号内的function返回值等于小括 ...
-
3.认识Angular2组件之1
简述:组件(component)是构成Angular应用的基础和核心.可以这样说,组件用来包装特定的功能,应用程序的有序运行依赖于组件之间的协同工作. 1. 组件化标准:W3C为了统一组件化的标准方式 ...
-
WCF调错方法
1.在VS cmd里,输入wcftestclient.exe 2.添加Service服务. 3.点击要测试的方法,输入参数,点击Invoke. 4.如果错误信息很模糊,则修改WCF程序所在的Web.c ...