day 42 常用的四种IO模型

今日内容概要

  • IO模型

IO模型简介

"""
五种IO Model:
    * blocking IO   阻塞IO
    * nonblocking IO   非阻塞IO
    * IO multiplexing   IO多路复用
    * signal driven IO   信号驱动IO
    * asynachronous IO   异步IO
"""
常见的网络阻塞状态:
    accept
    recv
    recvfrom

阻塞IO模型

import socket

server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)

while True:
    conn, addr = server.accept()
    while True:
        try:
            data = conn.recv(1024)
            if len(data) ==0:break
            print(data)
            conn.send(data.upper())
        except ConnectionResetErroe as e:
            break
    conn.close()

非阻塞IO

import socket
import time

server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.liten(5)
server.setblockding(False)
# 将所有的网络阻塞变为非阻塞
# 服务端
r_list = []
del_list = []
while True:
    try:
        conn, addr = server.accept()
        r_list.append(conn)
    except BlockingIOError:
        for conn in r_list:
            try:
                data = conn.recv(1024) # 没有消息  报错
                if len(data) == 0:
                    conn.close()
                    del_list.append(conn)
                    continue
                conn.send(data.upper())
                except BlockingIOError:
                    conn.close()
                    def_list.append(conn)
        for conn in del_list:
            r_list.remove(conn)
        def_list.clear()
        
        
# 客户端
import socket

client = socket.socket()
client.connect(('127.0.0.1', 8080))

while True:
    cliend.send(b'hello world')
    data = client.recv(1024)
    print
    
    
# 总结
"""
非阻塞IO模型会长时间占用着CPU并且不干活,让CPU不停的空转
实际应用中不会考虑使用非阻塞IO模型
"""

IO多路复用

"""
当监管的对象只有一个时,IO多路复用连阻塞IO都比不上
但是IO多路复用可以一次性监管很多对象

"""


import socket
import select

server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
server.setblocking(False)
read_list = [server]

while True:
    r_list, w_list, x_list =select.select(read_list, [], [])
    for i in r_list:
        if i is server:
            conn, addr = i.accept()
            read_list.append(conn)
        else:
            res = i.recv(1024)
            if len(res) == 0:
                i.close()
                read_list.remove(i)
                continue
            print(res)
            i.send(b'hahahahaha')
            
# 客户端
import socket

client = socket.socket()
client.connect(('127.0.0.1', 8080))

while True:
    client.send(b'hello world')
    data = client.recv(1024)
    print(data)

异步IO

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

import threading
import asyncio

@asyncio.coroutine
def hello():
    print('hello world %s' % threading.current_thread())
    yield from asyncio.sleep(1) # 换成真正的IO操作
    print('hello world %s' % threading.current_thread())
    
loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

上一篇:采用JDBC 连接MySQL 数据库并查询数据


下一篇:数据采集第二次实践