IO多路复用技术

IO多路复用

select 多路复用技术

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

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

POLL只是突破了连接的限制

上代码:

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已实现无数连接 轮询

epoll 改成事件通知

只能在Linux上使用 不能在window使用

上代码:

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 采用这个机制

转载于:https://my.oschina.net/u/3978509/blog/2988724

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值