国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Linux_epoll

這篇具有很好參考價值的文章主要介紹了Linux_epoll。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

思考:高效的餐廳服務(wù)如何實現(xiàn)?

一個顧客來就餐,一個服務(wù)員在顧客點菜期間全程陪同服務(wù)!
一個人來就餐,一個服務(wù)員去服務(wù),然后客人會看菜單,點菜。 服務(wù)員將菜單給后廚。
二個人來就餐,二個服務(wù)員去服務(wù)……
五個人來就餐,五個服務(wù)員去服務(wù)……
一百個人呢?
如果你是餐廳的老板,你改怎么解決?
Linux_epoll

Epoll - Reactor 設(shè)計模式

Linux_epoll
Linux_epoll

Epoll 與 Reactor 設(shè)計模式的關(guān)系

Epoll是一種I/O多路復(fù)用機制,而Reactor是一種事件驅(qū)動的設(shè)計模式。它們之間有密切的聯(lián)系,可以說Epoll是Reactor模式的一種實現(xiàn)方式。

Reactor模式是一種用于處理并發(fā)I/O操作的設(shè)計模式,其核心思想是將I/O操作分離成兩個階段:事件分發(fā)和事件處理。在事件分發(fā)階段,Reactor模式使用一個事件循環(huán)來等待事件的發(fā)生,并將事件分發(fā)給相應(yīng)的事件處理器。在事件處理階段,事件處理器執(zhí)行相應(yīng)的業(yè)務(wù)邏輯,從而完成對事件的處理。

Epoll是Linux內(nèi)核提供的一種I/O多路復(fù)用機制,它可以同時監(jiān)控多個文件描述符,當(dāng)其中任意一個文件描述符有事件發(fā)生時,Epoll會通知應(yīng)用程序進(jìn)行相應(yīng)的處理。在Reactor模式中,事件分發(fā)階段可以使用Epoll來實現(xiàn),通過將文件描述符注冊到Epoll中,等待事件的發(fā)生,并將事件通知給相應(yīng)的事件處理器來處理。

因此,可以說Epoll是Reactor模式的一種實現(xiàn)方式,它提供了高效的I/O事件通知機制,可以幫助應(yīng)用程序?qū)崿F(xiàn)高并發(fā)、高性能的網(wǎng)絡(luò)通信。在實際應(yīng)用中,通常會結(jié)合使用Epoll和Reactor模式,以實現(xiàn)更加高效的網(wǎng)絡(luò)編程。

Reactor優(yōu)點

1)響應(yīng)快,不必為單個同步事件所阻塞,雖然Reactor本身依然是同步的;
2)編程相對簡單,可以最大程度的避免復(fù)雜的多線程及同步問題,并且避免了多線程/進(jìn)程的切換開銷;
3)可擴(kuò)展性,可以方便的通過增加Reactor實例個數(shù)來充分利用CPU資源;
4)可復(fù)用性,reactor框架本身與具體事件處理邏輯無關(guān),具有很高的復(fù)用性;

Epoll - IO多路復(fù)用的用法

  1. 創(chuàng)建EPOLL 句柄(這一步和select、poll都不一樣,select與poll都是在while循環(huán)中,直接使用select函數(shù)、poll函數(shù),不需要創(chuàng)建句柄)
    int epoll_create(int size);

  2. 向EPOLL對象中添加、修改或者刪除感興趣的事件
    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

  • op取值:
    EPOLL_CTL_ADD 添加新的事件到epoll中
    EPOLL_CTL_MOD 修改EPOLL中的事件
    EPOLL_CTL_DEL 刪除epoll中的事件

  • events取值:
    EPOLLIN 表示有數(shù)據(jù)可以讀出(接受連接、關(guān)閉連接)
    EPOLLOUT 表示連接可以寫入數(shù)據(jù)發(fā)送(向服務(wù)器發(fā)起連接,連接成功事件)
    EPOLLERR 表示對應(yīng)的連接發(fā)生錯誤
    EPOLLHUP 表示對應(yīng)的連接被掛起

  1. 收集在epoll監(jiān)控的事件中已經(jīng)發(fā)生的事件(拿到已就緒的事件
    int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

epfd: epoll的描述符。

events:則是分配好的 epoll_event結(jié)構(gòu)體數(shù)組,epoll將會把發(fā)生的事件復(fù)制到 events數(shù)組中(events不可以是空指針,內(nèi)核只負(fù)責(zé)把數(shù)據(jù)復(fù)制到這個 events數(shù)組中,不會去幫助我們在用戶態(tài)中分配內(nèi)存。內(nèi)核這種做法效率很高)。

maxevents: 本次可以返回的最大事件數(shù)目,通常maxevents參數(shù)與預(yù)分配的events數(shù)組的大小是相等的

timeout: 表示在沒有檢測到事件發(fā)生時最多等待的時間(單位為毫秒),如果 timeout為0,立刻返回,不會等待。-1表示無限期阻塞

  1. 關(guān)鍵結(jié)構(gòu):
struct epoll_event{
	__uint32_t  events;
	epoll_data_t data;
};

typedef union epoll_data{
	void *ptr;
	int fd;//該事件的文件描述符
	uint32_t u32;
	uint64_t u64;
}epoll_data_t;

web_server示例代碼

// epoll_web_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <assert.h>
#include <fcntl.h>
#include <unistd.h>

//    int fd;
typedef struct _ConnectStat ConnectStat;

typedef void (*response_handler)(ConnectStat *stat);

struct _ConnectStat
{
    int fd;
    char name[64];
    char age[64];
    struct epoll_event _ev;
    int status;               // 0 -未登錄   1 - 已登陸
    response_handler handler; // 不同頁面的處理函數(shù)
};

// http協(xié)議相關(guān)代碼
ConnectStat *stat_init(int fd);
void connect_handle(int new_fd);
void do_http_respone(ConnectStat *stat);
void do_http_request(ConnectStat *stat);
void welcome_response_handler(ConnectStat *stat);
void commit_respone_handler(ConnectStat *stat);

const char *main_header = "HTTP/1.0 200 OK\r\nServer: Martin Server\r\nContent-Type: text/html\r\nConnection: Close\r\n";

static int epfd = 0;

void usage(const char *argv)
{
    printf("%s:[ip][port]\n", argv);
}

void set_nonblock(int fd)
{
    int fl = fcntl(fd, F_GETFL);
    fcntl(fd, F_SETFL, fl | O_NONBLOCK);
}

int startup(char *_ip, int _port) // 創(chuàng)建一個套接字,綁定,檢測服務(wù)器
{
    // sock
    // 1.創(chuàng)建套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0)
    {
        perror("sock");
        exit(2);
    }
    printf("來到端口復(fù)用\n");
    // 端口復(fù)用
    int opt = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    // 2.填充本地 sockaddr_in 結(jié)構(gòu)體(設(shè)置本地的IP地址和端口)
    struct sockaddr_in local;
    local.sin_port = htons(_port);
    local.sin_family = AF_INET;
    local.sin_addr.s_addr = inet_addr(_ip);
    printf("來到綁定\n");
    // 3.bind()綁定
    if (bind(sock, (struct sockaddr *)&local, sizeof(local)) < 0)
    {
        perror("bind");
        exit(3);
    }
    printf("服務(wù)端綁定成功\n");
    // 4.listen()監(jiān)聽 檢測服務(wù)器
    if (listen(sock, 5) < 0)
    {
        perror("listen");
        exit(4);
    }
    printf("服務(wù)端監(jiān)聽成功\n");
    // sleep(1000);
    return sock; // 這樣的套接字返回
}

int main(int argc, char *argv[]) // 提供兩個參數(shù) ip port
{
    printf("============1================\n");
    if (argc != 3) // 檢測參數(shù)個數(shù)是否正確
    {
        usage(argv[0]);
        exit(1);
    }
    printf("============2================\n");
    int listen_sock = startup(argv[1], atoi(argv[2])); // 創(chuàng)建一個綁定了本地 ip 和端口號的套接字描述符
    printf("============3================\n");
    // 1.創(chuàng)建epoll
    epfd = epoll_create(256); // 可處理的最大句柄數(shù)256個
    if (epfd < 0)
    {
        perror("epoll_create");
        exit(5);
    }
    printf("============4================\n");
    struct epoll_event _ev; // epoll結(jié)構(gòu)填充
    ConnectStat *stat = stat_init(listen_sock);
    _ev.events = EPOLLIN; // 初始關(guān)心事件為讀
    _ev.data.ptr = stat;
    //_ev.data.fd = listen_sock;    //
    printf("============5================\n");
    // 2.托管
    epoll_ctl(epfd, EPOLL_CTL_ADD, listen_sock, &_ev); // 將listen sock添加到epfd中,關(guān)心讀事件

    struct epoll_event revs[64];

    int timeout = -1;
    int num = 0;
    int done = 0;
    printf("============5================\n");
    while (!done)
    {
        printf("============6================\n");
        // epoll_wait()相當(dāng)于在檢測事件//比如說來了10事件,他會copy到revs里面來,然后你遍歷i=0;i<10;i++即可
        switch ((num = epoll_wait(epfd, revs, 64, timeout))) // 返回需要處理的事件數(shù)目  64表示 事件有多大
        {
        case 0: // 返回0 ,表示監(jiān)聽超時
            printf("timeout\n");
            printf("============7================\n");
            break;
        case -1: // 出錯
            perror("epoll_wait");
            printf("============8================\n");
            break;
        default: // 大于零 即就是返回了需要 處理事件的數(shù)目
        {
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            printf("============9================\n");
            int i;
            for (i = 0; i < num; i++)
            {
                ConnectStat *stat = (ConnectStat *)revs[i].data.ptr;

                int rsock = stat->fd;                                    // 準(zhǔn)確獲取哪個事件的描述符
                if (rsock == listen_sock && (revs[i].events) && EPOLLIN) // 如果是初始的 就接受,建立鏈接
                {
                    int new_fd = accept(listen_sock, (struct sockaddr *)&peer, &len);

                    if (new_fd > 0)
                    {
                        printf("get a new client:%s:%d\n", inet_ntoa(peer.sin_addr), ntohs(peer.sin_port));
                        // sleep(1000);
                        connect_handle(new_fd);
                    }
                }
                else // 接下來對num - 1 個事件處理
                {
                    if (revs[i].events & EPOLLIN)
                    {
                        do_http_request((ConnectStat *)revs[i].data.ptr);
                    }
                    else if (revs[i].events & EPOLLOUT)
                    {
                        do_http_respone((ConnectStat *)revs[i].data.ptr);
                    }
                    else
                    {
                    }
                }
            }
        }
        break;
        } // end switch
    }     // end while
    return 0;
}

ConnectStat *stat_init(int fd)
{
    ConnectStat *temp = NULL;
    temp = (ConnectStat *)malloc(sizeof(ConnectStat));

    if (!temp)
    {
        fprintf(stderr, "malloc failed. reason: %m\n");
        return NULL;
    }

    memset(temp, '\0', sizeof(ConnectStat));
    temp->fd = fd;
    temp->status = 0;
    // temp->handler = welcome_response_handler;
}

// 初始化連接,然后等待瀏覽器發(fā)送請求
void connect_handle(int new_fd)
{
    ConnectStat *stat = stat_init(new_fd);
    set_nonblock(new_fd);

    stat->_ev.events = EPOLLIN;
    stat->_ev.data.ptr = stat;

    epoll_ctl(epfd, EPOLL_CTL_ADD, new_fd, &stat->_ev); // 二次托管
}

void do_http_respone(ConnectStat *stat)
{
    stat->handler(stat);
}

void do_http_request(ConnectStat *stat)
{

    // 讀取和解析http 請求
    char buf[4096];
    char *pos = NULL;
    // while  header \r\n\r\ndata
    ssize_t _s = read(stat->fd, buf, sizeof(buf) - 1);
    if (_s > 0)
    {
        buf[_s] = '\0';
        printf("receive from client:%s\n", buf);

        pos = buf;

        // Demo 僅僅演示效果,不做詳細(xì)的協(xié)議解析
        if (!strncasecmp(pos, "GET", 3))
        {
            stat->handler = welcome_response_handler;
        }
        else if (!strncasecmp(pos, "Post", 4))
        {
            // 獲取 uri
            printf("---Post----\n");
            pos += strlen("Post");
            while (*pos == ' ' || *pos == '/')
                ++pos;

            if (!strncasecmp(pos, "commit", 6))
            { // 獲取名字和年齡
                int len = 0;

                printf("post commit --------\n");
                pos = strstr(buf, "\r\n\r\n");
                char *end = NULL;
                if (end = strstr(pos, "name="))
                {
                    pos = end + strlen("name=");
                    end = pos;
                    while (('a' <= *end && *end <= 'z') || ('A' <= *end && *end <= 'Z') || ('0' <= *end && *end <= '9'))
                        end++;
                    len = end - pos;
                    if (len > 0)
                    {
                        memcpy(stat->name, pos, end - pos);
                        stat->name[len] = '\0';
                    }
                }

                if (end = strstr(pos, "age="))
                {
                    pos = end + strlen("age=");
                    end = pos;
                    while ('0' <= *end && *end <= '9')
                        end++;
                    len = end - pos;
                    if (len > 0)
                    {
                        memcpy(stat->age, pos, end - pos);
                        stat->age[len] = '\0';
                    }
                }
                stat->handler = commit_respone_handler;
            }
            else
            {
                stat->handler = welcome_response_handler;
            }
        }
        else
        {
            stat->handler = welcome_response_handler;
        }

        // 生成處理結(jié)果 html ,write

        stat->_ev.events = EPOLLOUT;
        // stat->_ev.data.ptr = stat;
        epoll_ctl(epfd, EPOLL_CTL_MOD, stat->fd, &stat->_ev); // 二次托管
    }
    else if (_s == 0) // client:close
    {
        printf("client: %d close\n", stat->fd);
        epoll_ctl(epfd, EPOLL_CTL_DEL, stat->fd, NULL);
        close(stat->fd);
        free(stat);
    }
    else
    {
        perror("read");
    }
}

void welcome_response_handler(ConnectStat *stat)
{
    const char *welcome_content = "\
<html lang=\"zh-CN\">\n\
<head>\n\
<meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n\
<title>This is a test</title>\n\
</head>\n\
<body>\n\
<div align=center height=\"500px\" >\n\
<br/><br/><br/>\n\
<h2>大家好,歡迎來到奇牛學(xué)院VIP 課!</h2><br/><br/>\n\
<form action=\"commit\" method=\"post\">\n\
尊姓大名: <input type=\"text\" name=\"name\" />\n\
<br/>芳齡幾何: <input type=\"password\" name=\"age\" />\n\
<br/><br/><br/><input type=\"submit\" value=\"提交\" />\n\
<input type=\"reset\" value=\"重置\" />\n\
</form>\n\
</div>\n\
</body>\n\
</html>";

    char sendbuffer[4096];
    char content_len[64];

    strcpy(sendbuffer, main_header);
    snprintf(content_len, 64, "Content-Length: %d\r\n\r\n", (int)strlen(welcome_content));
    strcat(sendbuffer, content_len);
    strcat(sendbuffer, welcome_content);
    printf("send reply to client \n%s", sendbuffer);

    write(stat->fd, sendbuffer, strlen(sendbuffer));

    stat->_ev.events = EPOLLIN;
    // stat->_ev.data.ptr = stat;
    epoll_ctl(epfd, EPOLL_CTL_MOD, stat->fd, &stat->_ev);
}

void commit_respone_handler(ConnectStat *stat)
{
    const char *commit_content = "\
<html lang=\"zh-CN\">\n\
<head>\n\
<meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n\
<title>This is a test</title>\n\
</head>\n\
<body>\n\
<div align=center height=\"500px\" >\n\
<br/><br/><br/>\n\
<h2>歡迎學(xué)霸同學(xué)&nbsp;%s &nbsp;,你的芳齡是&nbsp;%s!</h2><br/><br/>\n\
</div>\n\
</body>\n\
</html>\n";

    char sendbuffer[4096];
    char content[4096];
    char content_len[64];
    int len = 0;

    len = snprintf(content, 4096, commit_content, stat->name, stat->age);
    strcpy(sendbuffer, main_header);
    snprintf(content_len, 64, "Content-Length: %d\r\n\r\n", len);
    strcat(sendbuffer, content_len);
    strcat(sendbuffer, content);
    printf("send reply to client \n%s", sendbuffer);

    write(stat->fd, sendbuffer, strlen(sendbuffer));

    stat->_ev.events = EPOLLIN;
    // stat->_ev.data.ptr = stat;
    epoll_ctl(epfd, EPOLL_CTL_MOD, stat->fd, &stat->_ev);
}

/*
sudo gcc epoll_web_server.c -o epoll_web_server
./epoll_web_server 192.168.52.128 8888
http://192.168.52.128:8888/

*/

水平觸發(fā)和邊緣觸發(fā)

  • Redis 水平觸發(fā)

  • Nginx 邊緣觸發(fā)

  • Level_triggered(水平觸發(fā)):當(dāng)被監(jiān)控的文件描述符上有可讀寫事件發(fā)生時,epoll_wait()會通知處理程序去讀寫。如果這次沒有把數(shù)據(jù)一次性全部讀寫完(如讀寫緩沖區(qū)太小),那么下次調(diào)用 epoll_wait()時,它還會通知你在上沒讀寫完的文件描述符上繼續(xù)讀寫,當(dāng)然如果你一直不去讀寫,它會一直通知你?。?!如果系統(tǒng)中有大量你不需要讀寫的就緒文件描述符,而它們每次都會返回,這樣會大大降低處理程序檢索自己關(guān)心的就緒文件描述符的效率?。?!
    設(shè)置方式: 默認(rèn)即水平觸發(fā)

  • Edge_triggered(邊緣觸發(fā)):當(dāng)被監(jiān)控的文件描述符上有可讀寫事件發(fā)生時,epoll_wait()會通知處理程序去讀寫。如果這次沒有把數(shù)據(jù)全部讀寫完(如讀寫緩沖區(qū)太小),那么下次調(diào)用epoll_wait()時,它不會通知你,也就是它只會通知你一次,直到該文件描述符上出現(xiàn)第二次可讀寫事件才會通知你!!!這種模式比水平觸發(fā)效率高,系統(tǒng)不會充斥大量你不關(guān)心的就緒文件描述符!??!
    設(shè)置方式: stat->_ev.events = EPOLLIN | EPOLLET

  • 如果你不設(shè)置,默認(rèn)就是水平觸發(fā)文章來源地址http://www.zghlxwxcb.cn/news/detail-474639.html

到了這里,關(guān)于Linux_epoll的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Linux學(xué)習(xí)記錄——??? 高級IO(6)--- Epoll型服務(wù)器(3)(Reactor)

    看完前兩篇再看這篇,本篇將會寫Reactor EpollServer.hpp中創(chuàng)建一個函數(shù)HandlerRequest,用它來做Recver函數(shù)的數(shù)據(jù)處理,也就是數(shù)據(jù)分析。 改一下回調(diào)函數(shù),不向外暴露Connection類。 Main.cc中就不需要兩個函數(shù),一個計算函數(shù)就可以 處理數(shù)據(jù)那里再加上最后的步驟 回到Recver函數(shù),調(diào)用

    2024年01月23日
    瀏覽(31)
  • 五、Linux C/C++ 對epoll-reactor服務(wù)器的百萬級高并發(fā)實現(xiàn)

    五、Linux C/C++ 對epoll-reactor服務(wù)器的百萬級高并發(fā)實現(xiàn)

    前言:基于epoll的反應(yīng)堆模式(reactor)的服務(wù)器程序,進(jìn)行百萬并發(fā)量的連接測試。通過代碼優(yōu)化,以及服務(wù)器與客戶端的硬件配置優(yōu)化,達(dá)到百萬并發(fā)。 代碼實現(xiàn) 代碼實現(xiàn): 1臺服務(wù)器:8G運行內(nèi)存 8核CPU 3臺客戶端:4G運行內(nèi)存 4核CPU 這些硬件配置可以通過虛擬機配置。 按照

    2024年02月20日
    瀏覽(35)
  • day-08 基于Linux的網(wǎng)絡(luò)編程(套接字和標(biāo)準(zhǔn)I/O、分離I/O流、epoll、多線程服務(wù)器)

    標(biāo)準(zhǔn)I/O函數(shù)(stdio)是在C語言中用于進(jìn)行輸入和輸出操作的庫函數(shù) 。它們包括了一組標(biāo)準(zhǔn)的輸入和輸出函數(shù),如printf、scanf、fopen、fclose等。標(biāo)準(zhǔn)I/O函數(shù)具有以下優(yōu)點: 簡單易用 :標(biāo)準(zhǔn)I/O函數(shù)提供了簡潔的接口,使得輸入和輸出操作變得簡單易用。開發(fā)人員無需自行處理底層

    2024年02月09日
    瀏覽(91)
  • 游戲思考26:游戲服務(wù)器壓力測試文檔(新增linux相關(guān)命令,02/10未完待續(xù))

    游戲思考26:游戲服務(wù)器壓力測試文檔(新增linux相關(guān)命令,02/10未完待續(xù))

    ①流量 ②內(nèi)存 ③一些主要的功能才做壓力測試,比如 同時注冊 , 最大在線 , 戰(zhàn)斗 , 地圖移動 , 數(shù)據(jù)存取 等。 ④2個壓力宏觀數(shù)據(jù)保持不變: a. 各接口的壓力比例不變 , 首先從同類型游戲或者本游戲內(nèi)測階段,日志插樁,收集各個接口的調(diào)用比例;然后,將接口比例

    2024年02月01日
    瀏覽(19)
  • 利用 ChatGPT 高效搜索:舉一反三的思考方式,高效查找解決方案

    利用 ChatGPT 高效搜索:舉一反三的思考方式,高效查找解決方案

    本文只是我的一些嘗試,基于 ChatGPT 實現(xiàn)系統(tǒng)化快速搜索某編程語言的特定領(lǐng)域相關(guān)包或者基于其他語言類推薦落地方案的嘗試。 這篇文章中描述的方式不一定是好方式,但應(yīng)該會有一定的啟示作用吧。讓 ChatGPT 為我們的開發(fā)效率添磚加瓦。 在學(xué)習(xí)和使用一門新的編程語言

    2024年01月18日
    瀏覽(15)
  • EMO:重新思考高效的基于注意力的移動塊模型

    論文鏈接:https://arxiv.org/pdf/2301.01146.pdf 本文的重點是在權(quán)衡參數(shù)、FLOPs和性能的同時,為密集預(yù)測開發(fā)現(xiàn)代、高效、輕量級的模型。倒立殘差塊(IRB)是輕量級CNN的基礎(chǔ)結(jié)構(gòu)#

    2024年02月15日
    瀏覽(13)
  • 【Linux】多路轉(zhuǎn)接 -- epoll

    【Linux】多路轉(zhuǎn)接 -- epoll

    epoll系統(tǒng)調(diào)用和select以及poll是一樣的,都是可以讓我們的程序同時監(jiān)視多個文件描述符上的事件是否就緒。 epoll在命名上比poll多了一個poll,這個e可以理解為extend, epoll就是為了同時處理大量文件描述符而改進(jìn)的poll。 epoll在2.5.44內(nèi)核中被引進(jìn),它幾乎具備了select和poll的所有

    2024年02月14日
    瀏覽(16)
  • linux--epoll

    linux--epoll

    參考文獻(xiàn) https://www.cnblogs.com/lojunren/p/3856290.html https://www.51cto.com/article/717096.html linux下的I/O復(fù)用epoll詳解 要深刻理解epoll,首先得了解epoll的三大關(guān)鍵要素:mmap、紅黑樹、鏈表。 首先需要了解什么是IO多路復(fù)用 IO多路復(fù)用是一種同步的IO模型。利用IO多路復(fù)用模型,可以實現(xiàn)一個

    2024年02月12日
    瀏覽(11)
  • Linux_epoll

    Linux_epoll

    一個顧客來就餐,一個服務(wù)員在顧客點菜期間全程陪同服務(wù)! 一個人來就餐,一個服務(wù)員去服務(wù),然后客人會看菜單,點菜。 服務(wù)員將菜單給后廚。 二個人來就餐,二個服務(wù)員去服務(wù)…… 五個人來就餐,五個服務(wù)員去服務(wù)…… 一百個人呢? 如果你是餐廳的老板,你改怎么

    2024年02月08日
    瀏覽(9)
  • Linux之epoll理解

    IO多路復(fù)用有幾種實現(xiàn)方式:select poll和epoll。本篇文章對epoll進(jìn)行總結(jié)理解。 IO多路復(fù)用的含義,我個人的理解是通過一個線程實現(xiàn)對多個socket的偵聽,epoll與select和poll的區(qū)別是epoll效率最高。 select的最高管理1024個socket并且是通過輪詢的方式實現(xiàn)的管理,管理的socket個數(shù)越多

    2024年02月07日
    瀏覽(9)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包