0、承上

  进程:

    计算机里最小的资源分配单位;

    数据隔离, 利用多核,数据不安全。

  线程:

    计算机中最小的CPU调度单位;

    数据共享,GIL锁,数据不安全.

  协程:

    线程的一部分,是有用户来调度的;

    数据共享,数据安全.

  异步:  同时做不止一件事情.

  同步:  事情一件接着一件 的做.

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

  非阻塞:平时遇见的处过上边基本上都是。

  IO操作:

    网络相关的操作

    文件处理、json.dump/load、logging、print、input、recv/send、connect/accept、recvfrom/sendto

  recv为什么要阻塞?

    等待数据到来到Python程序的内存中。

  IO模型一共有五种,由于信号驱动IO不常用,我们这里主要介绍阻塞IO、非阻塞IO、IO多路复用以及异步IO。

  对于一个network IO(这里以read举例),它会涉及到两个系统对象,一个是调用这个IO的process(or thread),另一个就是系统内核(kernel).当一个read操作发生时,该操作会经历两个阶段:

    (1)  等待数据准备( Waiting for the data to be ready )

    (2)  将数据从内核拷贝到进程中( Copying the data from the kernel to the process )

  这些IO模型的区别就在这两个阶段上各有不同.

1、阻塞IO( Blocking IO )

  在Linux中,默认情况下所有的socket都是blocking读操作流程大概如下:

  1. import socket
  2.  
  3. sk = socket.socket()
  4. sk.setblocking(True)
  5.  
  6. # True 阻塞
  7. # False 非阻塞
  8. # TCP协议的socket sever不能同时接收多个请求
  9. # sk.accept()
  10. # while True:
  11. # conn.recv()

2、非阻塞IO(non-blocking IO)

  非阻塞的形式实现了并发的socket server.

  非阻塞的形式实现了并发的socket sever,太耗CPU.

  没有数据来的时候程序的高速处理极大地占用了CPU资源.

  1. import socket
  2.  
  3. sk = socket.socket()
  4. sk.bind(('127.0.0.1', 9000))
  5. sk.setblocking(False)
  6. sk.listen()
  7. conn_lst = []
  8. del_lst = []
  9. while True:
  10. try:
  11. conn,addr = sk.accept() # 非阻塞,没有连接来就报错
  12. conn_lst.append(conn)
  13. print(conn)
  14. except BlockingIOError:
  15. for con in conn_lst:
  16. try:
  17. con.send(b'hello')
  18. try:
  19. print(con.recv(1024)) # 非阻塞 没有消息来就报错
  20. except BlockingIOError: # 没有消息就报错
  21. pass
  22. except ConnectionResetError: # send没有连接的报错
  23. con.close()
  24. del_lst.append(con)
  25. for con in del_lst:
  26. conn_lst.remove(con)
  27. del_lst.clear()

服务器端

  1. import socket
  2.  
  3. sk = socket.socket()
  4. sk.connect(('127.0.0.1', 9000))
  5. while True:
  6. print(sk.recv(1024))
  7. sk.send(b'bye')
  8. sk.close()

客户端

  sever:

结果:

  1. D:\Python36\python.exe E:/Python/草稿纸0.py
  2. <socket.socket fd=268, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 51839)>
  3. b'bye'
  4. b'byebye'
  5. b'bye'
  6. b'bye'
  7. b'bye'
  8. b'bye'
  9. b'bye'
  10. b'bye'
  11. b'bye'
  12. b'bye'
  13. b'bye'
  14. b'bye'
  15. b'bye'
  16. b'bye'
  17. b'bye'
  18. b'bye'
  19. b'bye'
  20. b'bye'
  21. b'bye'
  22. b'bye'
  23. b'bye'
  24. b'bye'
  25. b'bye'
  26. b'bye'
  27. b'bye'
  28. b'bye'
  29. b'bye'
  30. b'bye'
  31. b'bye'
  32. b'bye'
  33. b'bye'
  34. b'bye'
  35. b'byebye'
  36. b'bye'
  37. b'bye'
  38. b'bye'
  39. b'byebye'
  40. b'bye'
  41. b'bye'
  42. b'bye'
  43. b'bye'
  44.  
  45. Process finished with exit code 1

服务器端

  1. D:\Python36\python.exe E:/Python/草稿纸.py
  2. b'hello'
  3. b'hello'
  4. b'hello'
  5. b'hello'
  6. b'hello'
  7. b'hello'
  8. b'hello'
  9. b'hello'
  10. b'hello'
  11. b'hello'
  12. b'hello'
  13. b'hello'
  14. b'hello'
  15. b'hello'
  16. b'hello'
  17. b'hello'
  18. b'hello'
  19. b'hello'
  20. b'hello'
  21. b'hello'
  22. b'hello'
  23. b'hello'
  24. b'hello'
  25. b'hello'
  26. b'hello'
  27. b'hello'
  28. b'hello'
  29. b'hello'
  30. b'hello'
  31. b'hello'
  32. b'hellohellohello'
  33. b'hello'
  34. b'hello'
  35. b'hellohellohello'
  36. b'hello'
  37. b'hello'
  38. b'hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello'
  39. b'hellohello'
  40. b'hello'

客户端结果

  由于通信的一直是小数据块(大小不够1024),出现了黏包现象.

3、IO多路复用(IO multiplexing)

  1. import select
  2. import socket
  3.  
  4. sk = socket.socket()
  5. sk.bind(('127.0.0.1', 9000))
  6. sk.setblocking(False)
  7. sk.listen()
  8.  
  9. rlst = [sk] # 监听的是对象的读操作
  10. wlst = [] # 监听的是对象的写操作
  11. xlst = [] # 监听的是对象的异常操作
  12. while True:
  13. rl,wl,xl = select.select(rlst, wlst, xlst)
  14. for obj in rl:
  15. if obj == sk:
  16. conn,addr = sk.accept()
  17. rlst.append(conn)
  18. else:
  19. msg = obj.recv(1024)
  20. if msg == b'':
  21. obj.close()
  22. rlst.remove(obj)
  23. continue
  24. print(msg)
  25. obj.send(b'hello')

IO多路复用-sever端

  1. import socket
  2.  
  3. sk = socket.socket()
  4. sk.connect(('127.0.0.1', 9000))
  5. while True:
  6. sk.send(b'wahaha')
  7. print(sk.recv(1024))
  8. sk.close()

IO多路复用-client端

  socketsever —— TCP协议的并发操作  selectors + 多线程

  IO多路复用的select的工作机制

    select  Windows  轮询

    poll      Linux        轮询,poll能够监听的对象比select要多

    epoll    Linux        不是采用轮询的方式,而是采用回调函数的形式

Python_阻塞IO、非阻塞IO、IO多路复用的更多相关文章

  1. IO多路复用,同步,异步,阻塞和非阻塞 区别

    一.什么是socket?什么是I/O操作? 我们都知道unix(like)世界里,一切皆文件,而文件是什么呢?文件就是一串二进制流而已,不管socket,还是FIFO.管道.终端,对我们来说,一切都是 ...

  2. IO多路复用,同步,异步,阻塞和非阻塞 区别(转)

    转自:http://www.cnblogs.com/aspirant/p/6877350.html?utm_source=itdadao&utm_medium=referral 同步.异步 是 ...

  3. IO模型--阻塞IO,非阻塞IO,IO多路复用,异步IO

    IO模型介绍: * blocking IO 阻塞IO * nonblocking IO 非阻塞IO * IO multiplexing IO多路复用 * signal driven IO 信号驱动IO ...

  4. Python网络编程-IO阻塞与非阻塞及多路复用

    前言 问题:普通套接字实现的服务端的缺陷 一次只能服务一个客户端!                         accept阻塞! 在没有新的套接字来之前,不能处理已经建立连接的套接字的请求 re ...

  5. python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...

  6. {python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO模型比较分析 selectors模块

    python之IO多路复用 阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 ...

  7. 同步和异步 阻塞和非阻塞 IO多路复用和select总结

    同步和异步的概念 同步是指用户线程发起IO请求后,需要等待或者轮询内核IO操作完成后才能继续执行: 异步是指用户线程发起IO请求后仍继续执行,当内核IO操作完成后会通知用户线程或者调用用户线程注册的回 ...

  8. (IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    参考博客: https://www.cnblogs.com/xiao987334176/p/9056511.html 内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yi ...

  9. IO阻塞模型、IO非阻塞模型、多路复用IO模型

    IO操作主要包括两类: 本地IO 网络IO 本地IO:本地IO是指本地的文件读取等操作,本地IO的优化主要是在操作系统中进行,我们对于本地IO的优化作用十分有限 网络IO:网络IO指的是在进行网络操作 ...

  10. 网络IO之阻塞、非阻塞、同步、异步总结

    网络IO之阻塞.非阻塞.同步.异步总结 1.前言 在网络编程中,阻塞.非阻塞.同步.异步经常被提到.unix网络编程第一卷第六章专门讨论五种不同的IO模型,Stevens讲的非常详细,我记得去年看第一 ...

随机推荐

  1. 虚机抓取Hyper-V宿主的镜像流量(Windows Server 2012R2)

    1.将交换机流量镜像到Hyper-V宿主的一块网卡(eth4) 2.在Hyper-V宿主上新建虚拟交换机(Network_Mirror),选择外部网络,扩展属性中启用“Microsoft NDIS捕获 ...

  2. docker往阿里云推镜像和打包镜像

    向仓库推镜像 1. 登录到阿里云docker镜像站点,然后创建仓库. 2.要按照阿里云官方给定的仓库名称来使用,所以我们一般都要继续给准备要上传的镜像二次添加标签,如下所示: 3.在终端登录阿里云站点 ...

  3. Glyphicons 字体图标

  4. Unix/Linux环境C编程新手教程(21) 各个系统HelloWorld跑起来效果怎样?

    版权声明:本文为博主尹成联系QQ77025077,微信18510341407原创文章,欢迎转载侵权不究. https://blog.csdn.net/yincheng01/article/detail ...

  5. json_encode里面经常用到的 JSON_UNESCAPED_UNICODE和JSON_UNESCAPED_SLASHES

    php格式化json的函数json_encode($value,$options) 其中有2个比较常用到的参数 JSON_UNESCAPED_UNICODE(中文不转为unicode ,对应的数字 2 ...

  6. 【vue】饿了么项目的相关笔记链接

    http://www.mtons.com/content/1819.htm http://www.tuicool.com/articles/F7BnaiY https://segmentfault.c ...

  7. Redis之过期时间

    1.命令介绍 expire key seconds    设置key的有效时间,单位为秒expire命令返回1表示设置成功,返回0表示键不存在或设置失败. ttl keyttl命令返回值是键的剩余时间 ...

  8. SpringBoot之静态资源放行

    为了提高开发效率,编写对应的代码生成器.代码生成器主要有两个方面,一个是在线Web,另外一个是运行某个类. 使用的技术是SpringBoot+MyBatis-Plus+MySQL+JDK8. 在编写在 ...

  9. 简单使用普通用户启动tomcat

    新建用户tomcat,该用户不能登录 useradd tomcat -s '/sbin/nologin' 将/usr/local/tomcat/bin/startup.sh更名 mv /usr/loc ...

  10. nginx指定配置文件启动

    /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf