一、复习

  1、进程、线程、协程

    进程:是计算机中最小的资源分配单位,数据隔离,可以利用多核,数据不安全

线程:是计算机中最小的CPU调度单位,数据共享,GIL,数据不安全

    协程:是线程的一部分,是由用户来调度,数据共享,数据安全

  2、同步、异步、阻塞、非阻塞

      异步:同时做不止一件事

      同步:事情一件做完接着下一件

      阻塞:recv\recvfrom\accept\sleep\input

      非阻塞:

二、IO多路复用

    IO操作:

      文件处理:文件处理,json.dump/load,input,print,logging

      网络操作:recv/send,resvfrom/sendto,accept/connect

    # recv 为什么要阻塞
      # 等待数据来到我Python程序的内存里

  1.阻塞IO:

      

      

  2.非阻塞IO:

      

      

      代码举例:

      

# import time
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',9000))
sk.setblocking(False)
sk.listen()
conn_lst = []
del_lst = []
while True:
try:
conn,addr = sk.accept() #--> 非阻塞,没有连接来就报错
conn_lst.append(conn)
print(conn)
except BlockingIOError:
for con in conn_lst: # conn1,conn2,conn3
try:
con.send(b'hello')
try:
print(con.recv(1024)) # 非阻塞 没有消息来就报错
except BlockingIOError:pass # recv没有消息的报错
except ConnectionResetError: # send没有连接的报错
con.close()
del_lst.append(con)
for con in del_lst:
conn_lst.remove(con)
del_lst.clear() # 非阻塞的形式实现了并发的socket server
# 非阻塞的形式实现了并发的socket server,太耗cpu
# 没有数据来 的时候 程序的高速处理极大地占用了CPU资源

非阻塞IO-server

import socket

sk = socket.socket()
sk.connect(('127.0.0.1',9000))
while True:
print(sk.recv(1024))
sk.send(b'bye')
sk.close()

非阻塞IOclient

  3.IO多路复用:

      

      

import select
import socket sk = socket.socket()
sk.bind(('127.0.0.1',9000))
sk.setblocking(False)
sk.listen() rlst = [sk] # 监听的是对象的读操作
wlst = [] # 监听的是对象的写操作
xlst = [] # 监听的是对象的异常操作
while True:
rl,wl,xl = select.select(rlst,wlst,xlst) # [sk,conn]
for obj in rl: # [conn1,conn2]
if obj == sk:
conn,addr = sk.accept() # 每次建立连接的时候conn
rlst.append(conn)
else:
msg = obj.recv(1024)
if msg == b'':
obj.close()
rlst.remove(obj)
continue
print(msg)
obj.send(b'hello') # socketserver
# TCP协议的并发操作 selectors + 多线程

多路复用IO-select-sever

import socket

sk = socket.socket()
sk.connect(('127.0.0.1',9000))
while True:
sk.send(b'wahaha')
print(sk.recv(1024))
sk.close() # IO多路复用的select的工作机制
# select windows 轮询
# poll linux 轮询,poll能够监听的对象比select要多
# epoll linux 不是采用轮询的方式,而是采用回调函数的形式

多路复用IO-select-client

# IO多路复用的select的工作机制
# select windows  轮询
# poll   linux    轮询,poll能够监听的对象比select要多
# epoll  linux    不是采用轮询的方式,而是采用回调函数的形式

跨平台或平台自适应IO多路复用:

import selectors
import socket sel = selectors.DefaultSelector() def accept(obj,mask):
"""
回调函数,当selectors实例感知有用户连接服务器时,就会回调该函数。
:param obj:
:param mask:
:return:
"""
conn,addr = obj.accept()
sel.register(conn, selectors.EVENT_READ, read) # 注册用户连接conn到selector监听列表中 def read(conn,mask):
"""
回调函数,当selectors实例感知有用户发送数据时,就会回调该函数。
:param conn:
:param mask:
:return:
"""
try:
data = conn.recv(1024)
if not data: # 为空则抛出异常由下边的异常处理语句处理
raise Exception
conn.send(data+'_sb'.encode('utf-8'))
except Exception as e:
print('closing', conn)
sel.unregister(conn)
conn.close() sk = socket.socket()
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sk.bind(('127.0.0.1', 9000))
sk.listen()
sk.setblocking(False)
sel.register(sk, selectors.EVENT_READ, accept) while 1:
events = sel.select() # [sk,conn1,conn2...] 谁有新的数据就会返回谁
for key, mask in events:
callback = key.data # 回到函数
callback(key.fileobj, mask) # 执行回调函数

selectors-server

import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9000))
while 1:
inp = input('>>>')
sk.send(inp.encode('utf-8'))
print(sk.recv(1024).decode('utf-8'))

selectors-client

  4.异步IO:

      

  5.各种IO对比:

      

python全栈开发day36-IO多路复用的更多相关文章

  1. Python 全栈开发【第0篇】:目录

    Python 全栈开发[第0篇]:目录   第一阶段:Python 开发入门 Python 全栈开发[第一篇]:计算机原理&Linux系统入门 Python 全栈开发[第二篇]:Python基 ...

  2. 自学Python全栈开发第一次笔记

           我已经跟着视频自学好几天Python全栈开发了,今天决定听老师的,开始写blog,听说大神都回来写blog来记录自己的成长. 我特别认真的跟着这个视频来学习,(他们开课前的保证书,我也写 ...

  3. python全栈开发中级班全程笔记(第二模块、第四章)(常用模块导入)

    python全栈开发笔记第二模块 第四章 :常用模块(第二部分)     一.os 模块的 详解 1.os.getcwd()    :得到当前工作目录,即当前python解释器所在目录路径 impor ...

  4. Python全栈开发【面向对象进阶】

    Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...

  5. Python全栈开发【面向对象】

    Python全栈开发[面向对象] 本节内容: 三大编程范式 面向对象设计与面向对象编程 类和对象 静态属性.类方法.静态方法 类组合 继承 多态 封装 三大编程范式 三大编程范式: 1.面向过程编程 ...

  6. Python全栈开发【模块】

    Python全栈开发[模块] 本节内容: 模块介绍 time random os sys json & picle shelve XML hashlib ConfigParser loggin ...

  7. Python全栈开发【基础四】

    Python全栈开发[基础四] 本节内容: 匿名函数(lambda) 函数式编程(map,filter,reduce) 文件处理 迭代器 三元表达式 列表解析与生成器表达式 生成器 匿名函数 lamb ...

  8. Python全栈开发【基础三】

    Python全栈开发[基础三]  本节内容: 函数(全局与局部变量) 递归 内置函数 函数 一.定义和使用 函数最重要的是减少代码的重用性和增强代码可读性 def 函数名(参数): ... 函数体 . ...

  9. Python全栈开发【基础二】

    Python全栈开发[基础二] 本节内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典) 其他(编码,range,f ...

  10. Python全栈开发【基础一】

    Python全栈开发[第一篇] 本节内容: Python 的种类 Python 的环境 Python 入门(解释器.编码.变量.input输入.if流程控制与缩进.while循环) if流程控制与wh ...

随机推荐

  1. 《Two Dozen Short Lessons in Haskell》所有习题的索引

    <Two Dozen Short Lessons in Haskell>(Copyright © 1995, 1996, 1997 by Rex Page,有人翻译为Haskell二十四学 ...

  2. 小程序Promise不支持finally解决方案

    小程序Promise不支持finally解决方案 代码片段 点击链接即可在微信开发者工具中查看代码wechatide://minicode/t2eidemj7P3X git地址 基本思路 小程序的Pr ...

  3. sql server存储过程简单的使用

    --创建存储过程 create proc test_proc @date datetime as select * from t_user where times between ),),),),' ...

  4. deepin下codeblocks更改调试终端

    codeblocks建立控制台程序生成完毕后,发现自带的调试终端xterm不能进行复制粘贴操作参考了Ubuntu的更换调试终端的方法,就是把deepin下的deepin-terminal 用作调试终端 ...

  5. mysql 案例~ 主从复制转化为级联复制

    一 需求 mysql 主从复制切换成级联复制二 核心思想 1 开启级联复制 2 确定postion点场景 A->B A-C 三 切换步骤  1 先确定好B为级联复制库  2 B添加log_upd ...

  6. 文件打包(.zip)并返回打压缩包存放路径

    1.由于公司需要将一个或多个视频进行打包,格式如下图: 2.创建zipUtil工具包: package com.seegot.util; import java.io.BufferedOutputSt ...

  7. Java泛型方法与泛型类的使用------------(五)

    泛型的本质就是将数据类型也参数化, 普通方法的输入参数的值是可以变的,但是类型(比如: String)是不能变的,它使得了在面对不同类型的输入参数的时候我们要重载方法才行. 泛型就是将这个数据类型也搞 ...

  8. RPC原理

    RPC同步调用流程:(异步另说) 1)服务消费方(Client)以本地的调用方式调用远程服务. 2)客户端代理(Client Stub)接收到调用后负责将方法.参数等组装成能够进行网络传输的消息体. ...

  9. SpringBoot使用外置的Servlet容器

    SpringBoot默认使用嵌入式的Servlet容器,应用打包成可执行的jar包 优点:简单.便携 缺点:默认不支持jsp,优化定制比较复杂(使用定制器serverProperties.自定义Emb ...

  10. python计算最大公约数和最小公倍数

    a=4 b=2 def gcd(a,b): return a if b==0 else gcd(b,a%b) def lcm(a,b): return a*b//gcd(a,b) print(gcd( ...