• epoll 模板


    select 的问题:

    1.当进程被唤醒不清楚到底哪个socket有数据,只能遍历一遍

    2.每一次select的执行,都需要将这进程,再加入到等待队列中

    ​ 为了防止重复添加等待队列,当某一次操作完成时,也必须从等待队列中删除进程

    所以select最大限制被设置为了1024 ,如此看来select连多线程都比不上

    于是推出了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

    并发:

    多进程 开销大

    多线程 开销小于进程 但是不能无限开

    协程 避免线程数量达到上线的问题 本质上属于非阻塞IO模型

    IO模型 多路复用 是最好的解决方案

    面试官如果问到高并发,从进程开始介绍

  • 相关阅读:
    JQuery图片局部放大
    c# .net 如何使用log4net记录日志
    VS2010添加自定义的项目模板及项模板
    Virtualbox运行报cannot access the kernel driver的解决方法
    Session超时设置
    WebBrowser 错误处理
    asp.net MVC 2 自定义用户角色权限设计
    c# 调用CMD不显窗口
    C#遍历CookieContainer所有Cookie并保存到文件
    Application,Session,Cookie,ViewState和Cache区别
  • 原文地址:https://www.cnblogs.com/bladecheng/p/11164536.html
Copyright © 2020-2023  润新知