博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python 之IO模型
阅读量:6268 次
发布时间:2019-06-22

本文共 2571 字,大约阅读时间需要 8 分钟。

阻塞IO模型:以前写的套接字通信都是阻塞型的。通过并发提高效率

非阻塞IO模型:

from socket import *# 并不推荐使用,一是消耗cpu资源,二是会响应延迟server = socket(AF_INET, SOCK_STREAM)server.bind(('127.0.0.1',8087))server.listen(5)server.setblocking(False)conn_list = []wlist = []while True:   # 死循环,消耗cpu大    try:        conn,addr = server.accept() #等待连接        conn_list.append(conn)        print(conn_list)    except BlockingIOError:   # 如果没有客户端发送连接请求,干通信活        del_list=[]        # 收消息        for conn in conn_list:  # 如果有超多客户端时,可能会服务延迟            try:                data = conn.recv(1024)                if not data:                    del_list.append(conn)                    continue                wlist.append((conn,data.upper()))            except BlockingIOError:                continue            except Exception:                conn.close()                del_list.append(conn)        #发消息        del_wlist = []        for item in wlist:            try:                conn = item[0]                data = item[1]                conn.send(data)                del_list.append(item)            except BlockingIOError:                pass        for item in del_wlist:            wlist.remove(item)        for conn in del_list:            conn_list.remove(conn)server.close()

 

多路复用IO模型,又叫事件驱动IO,使用select模块或poll(epoll)实现。

select模块优点:只用单线程(进程)执行,占用资源少,同时能为多客户端提供服务。

缺点:select()接口并不是实现‘事件驱动’的最好选择,因为当套接字较多时,需要消耗大量时间去轮询。很多操作系统提供了更为高效的接口,如

linux提供了epoll,BSD提供了kqueue,Solaris提供了/dev/poll。。。

epoll更被推荐(采用异步方式,有回调机制,不需轮询),遗憾的是各操作系统提供的epoll接口差异很大。

selector模块能根据平台选择IO多路复用的不同机制

import socketimport selectserver = socket.socket()server.bind(('127.0.0.1', 8800))server.listen(5)# sock.setblocking(False)rlist = [server, ]  # 有新客户端连接时,sock变化wlist = []wdata = {}while 1:    rl, wl, el=select.select(rlist, wlist, [], 0.5) # 每过0.5s监听有变化的套接字(server或conn)    print('rl', rl)    print('wl', wl)    for sock in rl:        if sock == server:            conn,addr = sock.accept() # 客户端发消息时,conn变化            rlist.append(conn)  # 有变化的conn加入rlist            print('server working...')        else:            try:                data = sock.recv(1024)                # linux上                if not data:                    sock.close()                    rlist.remove(sock)                    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)

 

异步IO模型

 

转载于:https://www.cnblogs.com/stin/p/8549811.html

你可能感兴趣的文章
SqlServer--bat批处理执行sql语句1-osql
查看>>
Linux系列教程(十八)——Linux文件系统管理之文件系统常用命令
查看>>
laravel安装初体验
查看>>
用yum查询想安装的软件
查看>>
TIJ -- 吐司BlockingQueue
查看>>
数据库分页查询
查看>>
[编程] C语言枚举类型(Enum)
查看>>
[Javascript] Compose multiple functions for new behavior in JavaScript
查看>>
ASP.NET MVC性能优化(实际项目中)
查看>>
ES6里关于类的拓展(一)
查看>>
零元学Expression Blend 4 - Chapter 46 三分钟快速充电-设定Margin的小撇步
查看>>
Format Conditions按条件显示表格记录
查看>>
RichTextBox指定全部文字显示不同颜色及部分文字高亮颜色显示
查看>>
mysql优化----explain的列分析
查看>>
Python正则表达式
查看>>
Java中CAS详解
查看>>
Spring Boot Unregistering JMX-exposed beans on shutdown
查看>>
命令行man的帮助手册
查看>>
Ubuntu 16.04下为Android编译OpenCV 3.2.0 Manager
查看>>
poi 导入导出的api说明(大全)
查看>>