python实例解释五种IO模型(2)--------非阻塞式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")
            continue
        else:
            print(e)
            c.close()
            break
    else:
        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需要用户程序不断去调用系统调用,这个过程称为轮询。

全部评论

相关推荐

最近群里有很多同学找我看简历,问问题,主要就是集中在明年三月份的暑期,我暑期还能进大厂嘛?我接下来该怎么做?对于我来说,我对于双非找实习的一个暴论就是title永远大于业务,你在大厂随随便便做点慢SQL治理加个索引,可能就能影响几千人,在小厂你从零到一搭建的系统可能只有几十个人在使用,量级是不一样的。对双非来说,最难的就是约面,怎么才能被大厂约面试?首先这需要一点运气,另外你也需要好的实习带给你的背书。有很多双非的同学在一些外包小厂待了四五个月,这样的产出有什么用呢?工厂的可视化大屏业务很广泛?产出无疑是重要的,但是得当你的实习公司到了一定的档次之后,比如你想走后端,那么中厂后端和大厂测开的选择,你可以选择中厂后端(注意,这里的中厂也得是一些人都知道的,比如哈啰,得物,b站之类,不是说人数超过500就叫中厂),只有这个时候你再去好好关注你的产出,要不就无脑大厂就完了。很多双非同学的误区就在这里,找到一份实习之后,就认为自己达到了阶段性的任务,根本不再投递简历,也不再提升自己,玩了几个月之后,美其名曰沉淀产出,真正的好产出能有多少呢?而实际上双非同学的第一份实习大部分都是工厂外包和政府外包!根本无产出可写😡😡😡!到了最后才发现晚了,所以对双非同学来说,不要放过任何一个从小到中,从中到大的机会,你得先有好的平台与title之后再考虑你的产出!因为那样你才将将能过了HR初筛!我认识一个双非同学,从浪潮到海康,每一段都呆不久,因为他在不断的投递和提升自己,最后去了美团,这才是双非应该做的,而我相信大部分的双非同学,在找到浪潮的那一刻就再也不会看八股,写算法,也不会打开ssob了,这才是你跟别人的差距。
迷茫的大四🐶:我也这样认为,title永远第一,只有名气大,才有人愿意了解你的简历
双非本科求职如何逆袭
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务