【IO模型】

Stevens一共有5种IO Model:
  1.blocking IO 阻塞  -------------常见的网络阻塞状态:accept、recv、recvfrom

  2.nonblocking IO 非阻塞
  3.IO multiplexing IO多路复用
  4.signal driven IO 信号驱动IO
  5.asynchronous IO 异步IO
    由signal driven IO(信号驱动IO)在实际中并不常用,所以主要介绍剩下的四种IO Model(IO多路复用、异步IO)。

 

(阻塞IO模型)

 

 1 import socket
 2 
 3 server = socket.socket()
 4 server.bind(('127.0.0.1', 6969))
 5 server.listen(5)
 6 
 7 while True:
 8     conn, addr = server.accept()
 9     while True:
10         try:
11             data = conn.recv(1024)
12             if len(data) == 0: break
13             print(data)
14             conn.send(data.upper())
15         except ConnectionResetError as e:
16             break
17     conn.close()
18 # 在服务端开设多进程或者多线程,其实还是没有解决IO问题,该等的地方还是在等,没有规避,只不过多个人等待的彼此过程中互不干扰

 

(非阻塞IO模型)

虽然非阻塞IO看起来非常的厉害,但该模型会长时间占用CPU不干活,让CPU处于空转的状态,

 

 1 服务端
 2 
 3 import socket, time
 4 
 5 server = socket.socket()
 6 server.bind(('127.0.0.1', 8888))
 7 server.listen(5)
 8 server.setblocking(True)  # 设置阻塞
 9 # 如果()内为False,则表示将所有的网络阻塞变为非阻塞,
10 
11 r_list = []
12 del_list = []
13 while True:
14     try:
15         conn, addr = server.accept()  # 立马阻塞
16         r_list.append(conn)
17     except BlockingIOError as e:
18         # time.sleep(2)
19         # print('列表的长度:',len(r_list))
20         # print('做其他事情')
21         for conn in r_list:
22             try:
23                 data = conn.recv(1024)  # 没有消息  报错
24                 if len(data) == 0:  # 客户端断开链接
25                     conn.close()
26                     # 将无用的conn从r_list删除
27                     del_list.append(conn)
28                     continue
            
conn.send(data.upper()
29             except BlockingIOError:
30                 continue
31             except ConnectionResetError:
32                 conn.close()
33                 del_list.append(conn)
34         # 挥手无用链接
35         for conn in del_list:
36             r_list.remove(conn)
37         del_list.remove(conn)
38 
39 =================================
40 客户端
41 
42 import socket
43 
44 client = socket.socket()
45 client.connect(('127.0.0.1', 8888))
46 
47 while True:
48     msg = input('>>>:')
49     client.send(b'hello world')
50     data = client.recv(1024)
51     print(data)

 

(多路复用)

当监管的对象只有一个的时候 其实IO多路复用连阻塞IO都比比不上!!!但是IO多路复用可以一次性监管很多个对象
监管机制是操作系统本身就有的 如果你想要用该监管机制(select)需要你导入对应的selectors模块

总结:
监管机制由很多
select机制 window linux都有
poll机制 只有linux有,poll机制和select机制基本一样,都可以监管多个对象,但是poll机制没有最大连接数的限制,在监管的时候肯会出现延时相应
epoll机制 只有linux有,给每个监管机制对象都绑定了一个回调机制,一旦有响应,回调机制立马发起提醒

 

 1 服务端
 2 
 3 import socket, select
 4 
 5 server = socket.socket()
 6 server.bind(('127.0.0.1', 8001))
 7 server.listen(5)
 8 server.setblocking(False)  # 设置阻塞
 9 read_list = [server]
10 while True:
11     r_list, w_list, x_list, = select.select(read_list, [], [])
12     for i in r_list:
13         if i is server:
14             conn, addr = i.accept()
15             # 也该添加到监管的队列中
16             read_list.append(conn)
17         else:
18             res = i.recv(1024)
19             if len(res) == 0:
20                 i.close()
21                 # 将无效的监管对象移除
22                 read_list.remove(i)
23                 continue
24             print(res)
25             i.send(b'OK')
26 
27 
28 ============================================
29 客户端
30 
31 import socket
32 
33 client = socket.socket()
34 client.connect(('127.0.0.1', 8001))
35 
36 while True:
37     38     client.send(b'hello world')
39     data = client.recv(1024)
40     print(data)

(异步IO)

异步IO模型是所有模型中效率最高的 也是使用最广泛的相关的模块和框架
模块:asyncio模块
异步框架:sanic、tronado、twisted
速度快

 

 1 import threading, asyncio
 2 
 3 
 4 @asyncio.coroutine
 5 def hello():
 6     print('Hello world!%s' % threading.current_thread())
 7     # 异步调用asyncio.sleep(1)
 8     yield from asyncio.sleep(1)
 9     print('Hello world%s' % threading.current_thread())
10 
11 
12 loop = asyncio.get_event_loop()
13 tasks = [hello(), hello()]
14 loop.run_until_complete(asyncio.wait(tasks))
15 loop.close()

总结

 

posted on 2024-06-26 20:14  认真的六六  阅读(30)  评论(0)    收藏  举报