I/O model
Coroutines are concurrency under a single thread, which does not improve performance. It must detect the I/O of multiple tasks under a single thread. Do not let it block when encountering I/O, and automatically switch to other tasks. Go; this can improve the operating efficiency under a single thread. The gevent module is used to implement it. How does gevent detect I/O behavior and automatically switch to other tasks when encountering I/O.
Synchronous and asynchronous, a synchronous call is to run the downlink code after submitting the task and wait for the result to get the result; an asynchronous call is to ignore it after submitting and then execute it. Asynchrony is usually used in conjunction with the callback mechanism. After I submit a task, this After the task runs, it will automatically trigger the callback function to run and hand over the result to it.
Synchronization is not necessarily blocking.
blocking I/O
#Blocking I/ O has no concurrency, just wait when blocked from socket import * from threading import Thread #Multi-threading can be used to achieve concurrency def communicate(conn): while True: try: data = conn.recv(1024) #等待 if not data: break conn.send(data.upper()) except ConnectionResetError: break conn.close() server = socket (AF_INET, SOCK_STREAM) server.bind(('127.0.0.1',8080)) server.listen(5) while True: print('starting...') conn, addr = server.accept() #wait stage is mainly stuck here print(addr) t =Thread(target=communicate,args=(conn,)) #Let the main thread do the accept work, and each link initiates a thread to let it do the communication work; I/ O blocking is not solved, and each operation does not affect each other t.start() #Thread pool ensures that the machine runs in a healthy state server.close()
from socket import * client = socket (AF_INET, SOCK_STREAM) client.connect(('127.0.0.1',8080)) while True: msg=input('>>: ').strip() if not msg:continue client.send(msg.encode('utf-8')) data=client.recv(1024) print(data.decode('utf-8')) client.close()
Non-blocking I/O
Monitor I/O under a single thread and help you automatically switch to another task
How are the wait and copy stages handled?
Same as gevent.
from socket import * server = socket (AF_INET, SOCK_STREAM) server.bind(('127.0.0.1',8083)) server.listen(5) server.setblocking(False) #True is blocking, False is non-blocking print('starting...') rlist=[] wlist = [] #send will also block when there is a large amount of data while True: try : conn, addr = server.accept() #Ask the operating system for data; the server can keep building links rlist.append(conn) print(rlist) except BlockingIOError: #Catch this exception #print( ' Do other work ' ) #You can do other work without data, #Receive message del_rlist = [] for conn in rlist: try: data=conn.recv(1024) if not data: del_rlist.append(conn) continue wlist.append((conn,data.upper())) #Store the socket and the data to be sent except BlockingIOError: continue except Exception: conn.close() del_rlist.append(conn) #send message del_wlist=[] for item in wlist: try: conn=item[0] data=item[1] conn.send(data) del_wlist.append(item) except BlockingIOError: # pass for item in del_wlist:#Successfully sent and deleted you wlist.remove(item) for conn in del_rlist: #Delete the conn that has no data sent rlist.remove(conn) server.close()
from socket import * client = socket (AF_INET, SOCK_STREAM) client.connect(('127.0.0.1',8083)) while True: msg=input('>>: ').strip() if not msg:continue client.send(msg.encode('utf-8')) data=client.recv(1024) print(data.decode('utf-8')) client.close()
Multiplexed I/O Model
from socket import * import select server = socket (AF_INET, SOCK_STREAM) server.bind(('127.0.0.1',8083)) server.listen(5) server.setblocking(False) print('starting...') rlist = [server,] #Specially store messageswlist = [] #Stored data wdata = {} while True: rl,wl,xl = select . select (rlist,wlist,[], 0.5 ) #Ask the operating system; [] indicates an abnormal print( ' rl ' ,rl) #rlist will keep a bunch of conn and server; wlist will keep a bunch of conn, once the buffer is not full, it can be sent print( ' wl ' ,wl) #wl is a socket that can send values to the buffer for sock in rl: if sock == server: #do the link work conn,addr=sock.accept() rlist.append(conn) else: try: data =sock.recv( 1024 ) if not data: #For linux system sock.close() rlist.remove(sock) #Do not monitor this socket continue wlist.append(sock) wdata[sock]=data.upper() except Exception: sock.close() rlist.remove(sock) ## for sock in wl: data=wdata[sock] sock.send(data) wlist.remove(sock) wdata.pop(sock) server.close()
from socket import * client = socket (AF_INET, SOCK_STREAM) client.connect(('127.0.0.1',8083)) while True: msg=input('>>: ').strip() if not msg:continue client.send(msg.encode('utf-8')) data=client.recv(1024) print(data.decode('utf-8')) client.close()
Asynchronous I/O Model