久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 108|回復: 0
收起左側(cè)

select poll, epoll

[復制鏈接]
ID:1154223 發(fā)表于 2025-6-16 19:52 | 顯示全部樓層 |閱讀模式
Select,Poll,Epoll是學習I/O多路復用必不可少的一節(jié),這章我將借用對這三個系統(tǒng)調(diào)用的講解,進一步加深對于I/O多路復用的理解
首先我們要知道為什么要有I/O多路復用,可以通過一次系統(tǒng)調(diào)用,檢查多個文件描述符的狀態(tài)。這是 I/O 多路復用的主要優(yōu)點,相比于非阻塞 I/O,在文件描述符較多的場景下,避免了頻繁的用戶態(tài)和內(nèi)核態(tài)的切換,減少了系統(tǒng)調(diào)用的開銷。
I/O 多路復用相當于將「遍歷所有文件描述符、通過非阻塞 I/O 查看其是否就緒」的過程從用戶線程移到了內(nèi)核中,由內(nèi)核來負責輪詢。
首先回憶一下,I/O多路復用是一種使用少數(shù)線程來監(jiān)聽多數(shù)網(wǎng)絡(luò)Socket的一種I/O方法,那么我們怎么使用I/O多路復用呢
Select
select使用一個固定大小的位圖來表示文件描述符fd的集合,調(diào)用select檢查這些fd的狀態(tài),每次調(diào)用select時都會重新構(gòu)建位圖,并將其傳遞給內(nèi)核,內(nèi)核來判斷是否有I/O已經(jīng)就緒
select的核心數(shù)據(jù)結(jié)構(gòu)是一個fd_set,        這是一個文件描述符集合,用來管理需要監(jiān)視的文件描述符
fd_set的核心是一個位圖(大小位1024),每一位對應著文件描述符的狀態(tài),1表示該描述符需要監(jiān)視,0表示該描述符不需要監(jiān)視
typedef __kernel_fd_set                fd_set;

#define __FD_SETSIZE        1024

typedef struct {
        unsigned long fds_bits[__FD_SETSIZE / (8 * sizeof(long))];
} __kernel_fd_set;
        select的函數(shù)原型如下
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

        可以看到,有三種fd_set
● readfds -- 可讀事件,用來監(jiān)視事件是否可讀
● writefds -- 可寫事件,用來監(jiān)視事件是否可寫
● exceptfds -- 描述符是否有異常情況
● nfds -- 要監(jiān)視的文件描述符的最大值+1
● timeout -- 可以選擇的監(jiān)視時間 可以是 阻塞(NULL),立即返回(0),或者指定的等待時間
1. 在調(diào)用select的是否我們需要把需要監(jiān)視的事件通過函數(shù)加入到對應的隊列中
2. 進入內(nèi)核態(tài)進行檢查,程序在調(diào)用select之后,內(nèi)核會歷遍對應的fd查看是否符合對應的狀態(tài)
  a. 符合:如果符合就把事件加入到readfds當中去
  b. 不符合:如果所有的都不符合就根據(jù)timeout來選擇等待的方式和事件
3. 返回,最后會返回符合要求的fd的數(shù)量
    while (1) {      
        fd_set rfds;
        fd_set wfds;
        int32_t maxfd = 0, res = 0;
        struct timeval timeout;
        
        timeout.tv_sec = 0;
        timeout.tv_usec = 500;
        
        FD_ZERO(&rfds);
        FD_ZERO(&wfds);
        
        FD_SET(socket1, &rfds);
        FD_SET(socket2, &rfds);
        
        maxfd = socket1 > socket2 ? socket1 : socket2;
        
        res = select(maxfd + 1, &rfds, NULL, NULL, &timeout);
        
        if (res < 0 && errno != EINTR && errno != 0) {
            // log it
            return;
        }
        
        if (FD_ISSET(socket1, &rfds)) {
            // do something
        }
        if (FD_ISSET(socket2, &rfds)) {
            // do something
        }
     }
        上面大致講解了如何使用select,這里其實我們可以很明顯的看出一個缺點的,
1. 就是我們并不返回符合要求的fd,而是把所有的fd都返回,所以返回到用戶態(tài)之后我們要進行fd的歷遍最終才能找到有相應的fd,這顯然是比較耗費事件的
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久伊人精品 | 黄色片久久 | 在线视频黄 | 日韩成人精品 | 日韩一级淫片 | 91污视频在线观看 | 国产一级片免费看 | 欧美在线观看一区 | 久久高清免费视频 | 婷婷激情综合 | 精品一区二区在线播放 | 日韩在线综合 | 午夜精品一区二区三区在线播放 | 五月婷婷深深爱 | 欧美手机在线 | www.久久.com| 久久香蕉精品 | 成人毛片100免费观看 | 91伊人网| 亚洲欧美另类在线观看 | 美日韩一区 | 国产精品国产三级国产aⅴ浪潮 | 色噜噜狠狠一区二区三区 | 亚洲日本久久 | 欧美日韩在线免费观看 | 日韩毛片免费看 | 秋霞午夜鲁丝一区二区老狼 | av免费在线观看网站 | 国产成人三级在线观看 | 婷婷视频在线 | 精品第一页 | 成人做爰免费视频免费看 | 黄色在线免费看 | 又色又爽又黄18网站 | 亚洲精品麻豆 | 91午夜精品亚洲一区二区三区 | 免费成人深夜夜行网站 | 伊人久久av | 精品欧美日韩 | 国产一区二区在线播放 | 久久国产成人 |