利用epoll 实现HTTP服务器的长链接与非堵塞

epoll是Linux内核2.5.44引入的一种高性能的多路I/O就绪通知机制,尤其适用于处理大量句柄。通过内存映射和事件就绪通知,epoll在HTTP服务器中可以实现非阻塞和长连接,避免了传统select/poll的轮询消耗,提高了服务器处理并发请求的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

epoll

epoll是什么?按照man手册的说法:是为处理大批量句柄而作了改进的poll。当然,这不是2.6内核才有的,它是在2.5.44内核中被引进的(epoll(4) is a new API introduced in Linux kernel 2.5.44),它几乎具备了之前所说的一切优点,被公认为Linux2.6下性能最好的多路I/O就绪通知方法。

epoll原理:

  • 内存映射(mmap): (共享内存,类似于公有变量 )新建一块不属于应用程序内存及操作系统内存,但两者都能调用的内存,将要操作的进程放进去
  • 事件就绪通知: 进程调动时(收到消息时)响应 ,epoll事先于公共内存里注册一个文件描述符,**文件描述符(fd)**就绪时就会激活进程,即收到数据时激活进程

区别于普通单进程单线程:

  • 普通单进程单线程HTTP服务器为轮询 select/poll(有/无数量限制的轮询)
  • 普通单进程单线程HTTP服务器是将应用程序内存内资源(进程)复制进操作系统内存,处理后删除

epell实现非阻塞长链接HTTP服务器:

# 创建一个epoll对象
epl = select.epoll()

# 将监听套接字对应的fd注册到epoll中
epl.register(tcp_server_socket.fileno(), select.EPOLLIN)

fd_event_dict = dict()

while True:

    fd_event_list = epl.poll()  # 默认会堵塞,直到 os监测到数据到来 通过事件通知方式 告诉这个程序,此时才会解堵塞

    # [(fd, event), (套接字对应的文件描述符, 这个文件描述符到底是什么事件 例如 可以调用recv接收等)]
    for fd, event in fd_event_list:
        # 等待新客户端的链接
        if fd == tcp_server_socket.fileno():
            new_socket, client_addr = tcp_server_socket.accept()
            epl.register(new_socket.fileno(), select.EPOLLIN)
            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:
                service_client(fd_event_dict[fd], recv_data)
            else:
                fd_event_dict[fd].close()
                epl.unregister(fd)
                del fd_event_dict[fd]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值