• linu平台下使用poll 和 epoll实现高并发


    poll 和 epoll

    poll只是简单对select进行了优化,但是还不够完美 ,epoll才是最后的解决方案

    注意:epoll仅能在linux中使用

    案例:

    import socket
    import select
    
    s = socket.socket()
    s.bind(("127.0.0.1",1689))
    s.listen()
    
    # 创建一个epoll对象
    epoll = select.epoll()
    
    # 注册读就绪事件 (有数据可以读取了)
    # s.fileno()用于获取文件描述符
    epoll.register(s.fileno(),select.EPOLLIN)
    
    
    # 存储文件描述符与socket的对应关系
    fd_sockets = {s.fileno():s}
    
    
    while True:
        # 该函数是阻塞会直到你关注的事件发生
        # 返回值为文件描述符与发生的事件类型  是一个列表 列表中是元组  第一个是描述符 第二个是事件
        for fd,event in epoll.poll():
            print("有socket 搞事情了!")
            sock = fd_sockets[fd] # 取出对应的socket对象
    
            # 判断socket是服务器还是客户端
            if sock == s:
                # 执行对应的接收或发送
                client,addr = sock.accept()
                # 注册客户端的事件
                epoll.register(client.fileno(),select.EPOLLIN)
                # 将对应关系存储到字典中
                fd_sockets[client.fileno()] = client
                print("来了一个客户端....")
                
            elif event == select.EPOLLIN: #客户端的处理
                data = sock.recv(1024)
                if not data:
                    epoll.unregister(fd) # 注销事件
                    fd_sockets.pop(fd) # 从字典中删除
                    sock.close()  # 关闭socket
                    continue
    
                print("%s 发来问候:%s" % (sock,data.decode("utf-8")))
    
                #将事件转换为可写
                epoll.modify(fd,select.EPOLLOUT)
            else:
                sock.send("我是服务器  你丫是谁?".encode("utf-8"))
                # 将事件转换为可读
                epoll.modify(fd, select.EPOLLIN)
    
    

    epoll 如何解决select的两个问题

    1.epoll 把对于等待队列的操作 与阻塞进程分开了

    2.epoll 自己维护了一个等待队列 避免了遍历所有socket

  • 相关阅读:
    Spring 总结
    分布式缓存Memcache
    Docker原理 -- namespace与CGroup
    JDK源码分析--Collections
    React生命周期总结
    【转】前端优化的35条
    http缓存与cdn相关技术
    跨域处理
    sequekize
    orm2
  • 原文地址:https://www.cnblogs.com/chuwanliu/p/11177147.html
Copyright © 2020-2023  润新知