day02

TCP服务端处理多客户端任务:
    原来是通过开启子进程来服务不同的客户端,当客户端退出时就关闭该子进程
多路复用:
    使用一个进程(有且只有一个主进程)同时监控若干个文件描述符,这种读写模式称为多路复用
    多用于TCP的服务端,用于监控客户端的连接和数据的收发
   
    优点:不需要频繁地创建、销毁进程,从而节约内存资源、时间资源,也避免了进程之间的竞争、等待
    缺点:要求单个客户端的任务不能太耗时,否则其他在等待的客户端就会感知“卡顿”
    适用场景:适合并发量大、但任务短小的场景,例如Web服务器

实现多路复用相关函数
    fd_set: 是文件描述符的集合,就是一种数据类型,使用以下函数进行操作
        void FD_ZERO(fd_set *set);
        功能:清空集合set,最好在一开始先清空集合再使用
        void FD_SET(int fd, fd_set *set);
        功能:向集合set中添加fd
        void FD_CLR(int fd, fd_set *set);
        功能:从集合set中删除fd
        int  FD_ISSET(int fd, fd_set *set);
        功能:判断集合set中是否存在fd
    返回值:存在返回1,不存在返回0

    int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
    功能:同时监控若干个文件描述符的读、写、异常
        nfds:被监控的文件描述符中最大值+1
        readfds:监控读操作的文件描述符集合
        writefds:监控写操作的文件描述符集合
        exceptfds:监控异常操作的文件描述符集合
        timeout:设置超时时间
            NULL    一直阻塞,直到某个被监控的描述符发生了对应的操作才返回
            0秒0微秒    非阻塞,直接返回
            大于0秒     等待该时间,超时了会返回0
                            如果设置超时时间,返回时该参数会变成剩余时间
        返回值:成功返回发生相应操作的文件描述符个数
                超时返回0   错误返回-1

    注意:readfds、writefds、exceptfds这三个参数既是输入也是输出,在调用时需往里面存放想要监控的文件描述符,当监控到发生操作时,该函数会给这三个参数只返回相应操作的文件描述符,存储在这三个参数中,需要调用者逐个判断获取

    select设计不合理的地方:
        1、每次调用select都需要向它传递要监控的描述符的集合
        2、当调用结束后如果想要知道哪些描述符发生了操作,需要拿所有被监控的描述符对着集合进行逐一测试

    select的优点:
        是最早出现的多路复用函数,几乎所有的操作系统都支持,系统的兼容性高


    只是select功能的部分增强,没有本质区别、缺点一致
    int pselect(int nfds, fd_set *readfds, fd_set *writefds,
                   fd_set *exceptfds, const struct timespec *timeout,
                   const sigset_t *sigmask);
    功能、原理与select大致类似
    区别:
        1、超时时间结构类型不同、pselect精度更高
        2、pselect的超时时间参数不会改变,因此无法获取剩余时间,但是select可以获取剩余时间,但是每次都需要重新设置
        3、pselect监控时可以通过sigmask参数设置想要屏蔽的信号,可以保障pselect在监控过程中不会被信号中断

poll:
    struct pollfd {
       int   fd;         /* 被监控的文件描述符 */
       short events;     /* 想要监控的事件 */
       short revents;    /* 实际监控到发生的事件 */
        //有以下事件
            POLLIN      普通优先级读事件
            POLLPRI     高优先级的读事件
            POLLOUT     写事件
            POLLRDHUP   对方socket关闭
            POLLERR     错误事件,无需监控也可发生
            POLLHUP     对方挂起事件,无需监控也可发生
            POLLNVAL    非法描述符事件
    };

    int poll(struct pollfd *fds, nfds_t nfds, int timeout);
    功能:监控文件描述符是否发生了相应的事件
    fds:pollfd结构连续内存的首地址
    nfds:要监控的fd的数量,也是要监控连续内存fds的成员数量
    timeout:设置超时时间   单位毫秒
    返回值:成功返回发生相应操作的文件描述符个数
            超时返回0   错误返回-1

epoll:
    int epoll_create(int size);
    功能:创建一个epoll对象,该对象用于保存要监控的描述符
    size:epoll对象能够保存的描述符数量
    返回值:成功返回epoll对象,失败负数

    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
    功能:控制epoll对象,添加、删除监控的描述符
    epfd:要操作的epoll对象描述符
    op:
        EPOLL_CTL_ADD   添加描述符    
        EPOLL_CTL_DEL   删除描述符
        EPOLL_CTL_MOD   修改描述符要监控的事件
    fd:epoll对象中要控制的描述符
    event:事件结构体
        struct epoll_event {
            uint32_t     events;      /* 要监控的事件,功能参考poll */
            epoll_data_t data;        /* User data variable */
        };
    返回值:成功0,失败-1

    int epoll_wait(int epfd, struct epoll_event *events,
                    int maxevents, int timeout);
    功能:监控epoll对象中的文件描述符,并返回产生事件的文件描述符
    epfd:要监控的epoll对象描述符
    events:输出型参数,用于获取发生事件的描述符数组
    maxevents:最多监控的描述符的数量
    timeout:超时时间ms
    返回值:成功返回发生事件的描述符数量
        0超时      1错误

    ***************************************************************
    epoll与select比较的优点:
        1、只需要设置一次要监控的描述符即可
        2、epoll会把发生了事件的描述符返回到结构体数组,只需要遍历该数组就可以处理所有发生了事件的描述符,但是select返回到集合中需要遍历全部被监控的描述符才能处理

    epoll的条件触发和边缘触发:
        条件触发:当文件缓冲区中有要读取的数据时,就会触发事件,也是epoll的默认触发

        边缘触发:当数据产生了发送的动作时就会触发且只触发一次,就算文件缓冲区中要有需要读取的数据也不触发事件
            1、把要监控的描述符事件增加EPOLLET  边缘触发选项
            2、要循环读取直到读完为止 while(-1!=recv)
            3、recv读取时必须以非阻塞方式读取MSG_DONTWAIT,否则会一直阻塞,形成死锁
            4、当recv返回-1时表示数据读取完毕,0表示断开
       
        优点:相比于条件触发,边缘触发能够大大降低触发的次数,从而提高epoll的效率
posted @   歪爱慕外  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示