热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python实例解释五种IO模型(2)非阻塞式IO

0.非阻塞式IO前面一篇博文解释了什么是阻塞式IO,你一定会发现这种IO存在的问题。在等待IO操作完成的过程中,进程会被投入睡眠,只能干
0. 非阻塞式IO

前面一篇博文解释了什么是阻塞式IO,你一定会发现这种IO存在的问题。在等待IO操作完成的过程中,进程会被投入睡眠,只能干等IO操作完成并返回。如果希望内核在进行IO操作的过程中进程继续运行,那么就需要用非阻塞式IO。
进程把一个套接字设置成非阻塞式,就是在通知内核,在你进行IO操作的过程中,不要把进程投入睡眠,IO操作没完成,返回一个错误即可。非阻塞IO的执行流程如下图所示。
在这里插入图片描述
这种IO在执行过程中,需要用户进程隔一段时间去调用一次系统调用,不断轮询,直到返回成功。下面看一个例子

1.例子

我们在上一篇博文的例子上做一下改变
服务端程序

import socket # 导入 socket 模块
import time
import errno
s = socket.socket() # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 12345 # 设置端口
s.bind((host, port)) # 绑定端口
s.listen(5) # 等待客户端连接
c, addr = s.accept() # 建立客户端连接
c.setblocking(False) #设置与客户端的连接socket为非阻塞式
print("connected from :%s:%s"%(addr[0],addr[1]))
while True:print("wating for client input")try:data = c.recv(1024)except socket.error as e:err = e.args[0]if err == errno.EAGAIN or err == errno.EWOULDBLOCK:time.sleep(1)print("no data available")continueelse:print(e)c.close()breakelse:data = str(data,'utf-8')print(data)if data == '88':c.close()break
print("client closed connection")
s.close()

客户端程序


import socket # 导入 socket 模块s = socket.socket() # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 12345 # 设置端口号s.connect((host, port))
print("connected to server")
while(True):data = input()s.send(bytes(data,'utf-8'))if data == '88':s.close()break

服务端建立与客户端的链接后,将socket设置为非阻塞式。对一个非阻塞式socket执行recv()函数,如果成功则返回读取到的数据,如果失败则抛出一个socket异常。
启动服务端程序
在这里插入图片描述
启动服务端程序后,客户端程序未启动,服务端阻塞在第9行,等待客户端连接。注意这个socket是服务端监听连接的socket,我们没有设置它非阻塞,默认是阻塞式的,因此程序在此处阻塞住。
然后,我们启动客户端程序
在这里插入图片描述
启动客户端程序后,连接成功,服务端读取客户端发来的数据。因为此时客户端没有写数据,因此服务器读取失败,recv()立即返回一个socket error,我们捕获这个error,隔一秒钟打印出"no data available"。
这个就是非阻塞式IO,系统调用在数据没准备好的时候,立即返回。这种IO需要用户程序不断去调用系统调用,这个过程称为轮询。


推荐阅读
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 深入理解Tornado模板系统
    本文详细介绍了Tornado框架中模板系统的使用方法。Tornado自带的轻量级、高效且灵活的模板语言位于tornado.template模块,支持嵌入Python代码片段,帮助开发者快速构建动态网页。 ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • Python 异步编程:深入理解 asyncio 库(上)
    本文介绍了 Python 3.4 版本引入的标准库 asyncio,该库为异步 IO 提供了强大的支持。我们将探讨为什么需要 asyncio,以及它如何简化并发编程的复杂性,并详细介绍其核心概念和使用方法。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • PyCharm下载与安装指南
    本文详细介绍如何从官方渠道下载并安装PyCharm集成开发环境(IDE),涵盖Windows、macOS和Linux系统,同时提供详细的安装步骤及配置建议。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文详细记录了在基于Debian的Deepin 20操作系统上安装MySQL 5.7的具体步骤,包括软件包的选择、依赖项的处理及远程访问权限的配置。 ... [详细]
  • 本文详细介绍如何使用arm-eabi-gdb调试Android平台上的C/C++程序。通过具体步骤和实用技巧,帮助开发者更高效地进行调试工作。 ... [详细]
  • 本文详细介绍了 GWT 中 PopupPanel 类的 onKeyDownPreview 方法,提供了多个代码示例及应用场景,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
author-avatar
问道摩托
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有