zoukankan      html  css  js  c++  java
  • epoll及实现http多任务(python)

    1.epoll用到了文件描述符的概念:

    首先,操作系统中一切皆文件


    文件与文件描述符fd

    文件是应用程序与系统(包括特定硬件设备)之间的桥梁,而文件描述符就是应用程序使用这个“桥梁”的接口。

    socket底层也是一个文件,socket.fileno()可以获得socket的文件描述符


    2.select与epoll:

    select:采用轮询的方式,客户端越多效率越低;需要将fd传入内核空间,内核处理后返回

    epoll:采用时间触发式,效率很高;epoll是用户空间和内核空间共用的,所以不用传fd

    EPOLLIN:表示对应的文件描述符可以读

    EPOLLOUT:表示对应的文件描述符可以写


    EPOLLIN的触发条件:

    有新连接请求

    客户端发送数据

    客户端正常断开连接

    另外,客户端异常断开连接,没触发任何事件



    3.python实现http多任务:

    import select


    1.创建一个epoll对象

    epoll = select.epoll() 

    2.将监听套接字对应的fd放到epoll中,并绑定事件,输入触发

    epoll.register(tcp_socket.fileno(), select.EPOLLIN)

    3.接收epoll检测到的事件及其对应的socket文件描述符,默认堵塞,直到内核检测到数据通知程序,才会解堵塞

      之前使用while True,内部设置非堵塞;所以一直在占用cpu资源;而有事件发生才执行,否则挂起,减少资源占用

      返回列表[(fd,event),(fd,event) . . .],event即EPOLLIN或EPOLLOUT

    list fd_event_list = epoll.poll()

    4.循环遍历列表,如果fd是接收客户端连接的socket,则程序调accept();如果是与客户端连接的socket,且事件是发送数据,则调recv()

    因为循环中只有fd,所以需要创建字典,保存accept()得到的new_socket,之后通过键fd来取得各new_socket


    fd_event_dict = dict()

    while True:  # 用来刷新新的事件
    list fd_event_list = epoll.poll()

    for fd, event in fd_event_list:
    if fd == tcp_socket.fileno():
    new_socket, client_addr = tcp_socket.accept()
    epoll.register(new_socket.fileno(), select.EPOLLIN)
    # 通过字典保存socket,键为fd,值为socket
    fd_event_dict[new_socket.fileno()] = new_socket
    elif event == select.EPOLLIN:
    # 判断已经链接的客户端是否有数据发送过来
    recv_data = fd_event_dict[fd].recv(1024).decode("utf-8")
    if recv_data:
    # 处理数据
                    . . .



    参考:

    socket 编程入门教程(一)TCP server 端:2、socket与文件描述符

    关于epoll版服务器的理解(Python实现)

    epoll的各个事件触发条件测试

  • 相关阅读:
    新的
    曾经写过得太监小说3《缱绻修真界》
    Python的from和import用法
    python几个有意思的小技巧
    leetcode 最长回文串
    leetcode-快速排序C++自写
    leetcode 面试题 01.06. 字符串压缩
    leeetcode 剑指 Offer 29. 顺时针打印矩阵
    leetcode 70. 爬楼梯 续
    leetcode 1143. 最长公共子序列-华为
  • 原文地址:https://www.cnblogs.com/justaman/p/11486640.html
Copyright © 2011-2022 走看看