是否需要显式使用 epoll_ctl ( fd , EPOLL_CTL_DEL , ... ) 来从红黑树里显式删除已关闭的套接字。一言与 C 知道的答案不对,代码验证是只用 close(fd) 即可

(1)关于 epoll 操作的三大系统函数: epoll_create ( … ) 、 epoll_ctl ( … ) 、 epoll_wait(…)。具体的函数原型略。这些函数完成了 epoll 对象的创建、 套接字往 epoll 红黑树中的添加、修改 与 删除 。 本文的整理的资料是, close ( fd_socket ) 后,是否需要手动把其从 epoll 红黑树里删除

(2) 以下为搜集的答案:

在这里插入图片描述

++以上答案来自某心一言,以下的回答来自 c 知道 :

在这里插入图片描述

(3)今天用代码验证了下, close ( sockFd ) 以后,就不要再使用 epoll_ctl ( EPOLL_MOD_DEL … ) 了,会报错误,描述符找不到, epoll 对象很智能啊

在这里插入图片描述

++ 给出代码版。本代码很简单,建立套接字启用监听后,扔到 epoll 对象里,就开始测试:

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <fcntl.h> //增加这俩头文件

int main( )
{   //验证被关闭的套接字是否会自动被 epoll对象剔除出红黑树
    int serv_sock, epfd ; // 套接字对象与 epoll对象的描述符
    struct sockaddr_in serv_adr; // 套接字的 ip地址与端口号
    struct epoll_event event   ; // 对应于套接字的事件

    serv_sock = socket(PF_INET,SOCK_STREAM,0);
    printf("创建了监听套接字,描述符为: %d\n",serv_sock);

    memset(&serv_adr,0,sizeof(serv_adr));
    serv_adr.sin_family = AF_INET  ;  // 协议
    serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址
    serv_adr.sin_port = htons( 80 );  // 监听端口号 80

    bind( serv_sock, (struct sockaddr *)&serv_adr, sizeof(serv_adr) ) ;
    listen(serv_sock,5);

    epfd = epoll_create( 50 ); // 随便给个数
    event.events  = EPOLLIN;    event.data.fd = serv_sock;

    //int epoll_ctl(int epfd, int op, int fd, epoll_event * event);
    epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event);//成0败-1并设置errno

    close(serv_sock); //删除套接字,那么它还在 epoll 红黑树中么?

    if( ! epoll_ctl(epfd, EPOLL_CTL_MOD, serv_sock, &event) )
        printf("验证发现: 被关闭的套接字仍在 epoll红黑树中\n");
    else
        perror("打印全局的 errno 错误信息:"); //测试发现会打印这一行
}

++ 测试结果如下:

在这里插入图片描述

++ 这说明,在新版本的 linux 内核里,扩充了系统函数 close(fd) 的功能,在关闭内存中的文件节点以前, close () 会发现有 epoll 对象引用了本 套接字,其会等待 epoll 的红黑树里删除了此套接字后,再关闭 套接字对应的文件节点
这里给出 linux 0.11 里的老版本 close() 的定义,扩充此 close()函数的功能还是可以做到的:

在这里插入图片描述

(4)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值