IO多路复用技术

IO多路复用

select 多路复用技术

  1. 32系统只能1024个链接 64位 2048个python

  2. 采用轮询机制,当并发大的时候,就会崩了缓存

POLL只是突破了链接的限制并发

上代码:app

from socket import *
import select


def main():
    # 建立对象
    tcp_server = socket(AF_INET, SOCK_STREAM)
    # 绑定地址
    tcp_server.bind(('', 8888))
    # 将主动模式设置为被动模式
    tcp_server.listen(5)
    # 初始化一个列表
    server_lists = [tcp_server]  # 将初始socket对象添加至列表中

    while True:
        sockets, _, _ = select.select(server_lists, [], [])
        for obj in sockets:
            if obj == tcp_server:
                # 建立新的链接
                new_socket, client_info = obj.accept()
                # 将新的new_socket对象添加至列表
                server_lists.append(new_socket)
                # 打印链接信息
                print(f'来自{client_info} 链接成功!')

            else:
                # 接收数据
                raw_data = obj.recv(1024)
                # 注意: 这个地方不能使用死循环,不然会致使阻塞状况,同一时总能一个客户端通讯,其余客户端将阻塞排队中,当前面断开是,后面的讲能够继续通讯
                if raw_data:
                    # 打印数据
                    print(f'接收到数据: {raw_data.decode("gb2312")}')
                else:
                    # 内容为空 移出链接信息
                    server_lists.remove(obj)
                    obj.close()


if __name__ == '__main__':
    main()

epoll 多路复用技术( 高并发 )

什么是epoll多路复用?

poll已实现无数链接 轮询socket

epoll 改为事件通知tcp

只能在Linux上使用 不能在window使用高并发

上代码:code

from socket import *
import select


def main():
    # 建立对象
    tcp_socket = socket(AF_INET, SOCK_STREAM)
    # 绑定地址
    tcp_socket.bind(('', 8888))
    # 将主动模式设置为被动模式
    tcp_socket.listen(5)
    # 建立epoll
    epoll = select.epoll()
    # 把被动套接字添加至监听读状态
    epoll.register(tcp_socket.fileno(), select.EPOLLIN)
    # 声明一个字典 用来存新建立套接字
    new_sockets = {}
    client_infos = {}
    while True:
        epoll_list = epoll.poll()
        for fd, _ in epoll_list:
            if fd == tcp_socket.fileno():
                # 建立新的链接
                new_socket, client_info = tcp_socket.accept()
                # 把新对象添加至监听
                epoll.register(new_socket.fileno(), select.EPOLLIN)
                # 添加至字典
                new_sockets[new_socket.fileno()] = new_socket
                client_infos[client_info] = client_info
                print(f'来自{client_info} 链接成功!')
            else:
                # 接收数据
                raw_data = new_sockets[fd].recv(1024)
                # 判断是否有数据
                if raw_data:
                    print(f'来自{client_info}的信息: {raw_data.decode("gb2312")}')
                else:
                    print('客户端已断开!')
                    # 客户端已关闭
                    new_sockets[fd].close()
                    # 注销监听队列
                    epoll.unregister(fd)
                    # 移除字典
                    del new_sockets[fd]
                    del client_infos


if __name__ == '__main__':
    main()

专业名词

  1. IO阻塞:Input output 输入输出 一写有一个缓存的东西 必定是读写操做 去缓存区取东西,若是没有就等待
  2. IO非阻塞:去缓存区取东西,无论有没有,必需得取,取到就正常,不然就异常
  3. 轮询:每一个人都要问一遍,很是耗时
  4. 事件通知机制:epoll 采用这个机制
相关文章
相关标签/搜索