Python examples explain five IO models (2) -------- non-blocking IO

0. Non-blocking IO

The previous blog post explained what blocking IO is, and you will definitely find problems with this IO. While waiting for the completion of the IO operation, the process will be put to sleep and can only wait for the completion of the IO operation and return. If you want the kernel to continue to run during the IO operation, then you need to use non-blocking IO.
When the process sets a socket to non-blocking, it is notifying the kernel that during your IO operation, do not put the process to sleep. The IO operation is not completed, just return an error. The execution flow of non-blocking IO is shown in the following figure.
Insert picture description here
During the execution of this type of IO, the user process needs to call a system call at intervals and poll continuously until it returns successfully. Let's look at an example

1. Examples

Let’s make a change on the example of the previous blog post. The
server program

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()

Client program


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

After the server establishes a connection with the client, the socket is set to non-blocking. Execute the recv() function on a non-blocking socket, and return the read data if it succeeds, and throw a socket exception if it fails.
Starting the server program After
Insert picture description here
starting the server program, the client program is not started, the server is blocked at line 9, waiting for the client to connect. Note that this socket is the socket for the server to monitor the connection. We did not set it to be non-blocking. The default is blocking, so the program is blocked here.
Then, we start the client program. After
Insert picture description here
starting the client program, the connection is successful and the server reads the data sent by the client. Because the client did not write data at this time, the server failed to read, recv() immediately returns a socket error, we capture this error, and print out "no data available" every second.
This is non-blocking IO. The system call returns immediately when the data is not ready. This kind of IO requires the user program to continuously call the system call. This process is called polling.

Guess you like

Origin blog.csdn.net/ww1473345713/article/details/85917322