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

Linux學習記錄——??? 高級IO(4)--- Epoll型服務器(1)

這篇具有很好參考價值的文章主要介紹了Linux學習記錄——??? 高級IO(4)--- Epoll型服務器(1)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


1、理解Epoll和對應接口

poll依然需要OS去遍歷所有fd。一個進程去多個特定的文件中等待,只要有一個就緒,就使用select/poll系統(tǒng)調(diào)用,讓操作系統(tǒng)把所有文件遍歷一遍,哪些就緒就加上哪些fd,再返回。一旦文件太多了,遍歷效率就顯而易見地低。epoll是為處理大批量句柄而作了改進的poll,句柄就是訪問某種資源時標識這個資源的東西,比如C語言中的FILE結構體,文件描述符等。不過select/poll并不是沒有用處,一些老型操作系統(tǒng)并不支持epoll,就得使用poll或者select。epoll是在Linux內(nèi)核2.5.44時引入的,到現(xiàn)在為止都是Linux中最高效的多路轉(zhuǎn)接IO方案。

epoll有3個接口。

Linux學習記錄——??? 高級IO(4)--- Epoll型服務器(1),Linux學習,服務器,linux,學習

size是一個被忽略的參數(shù),只要大于0就行。如果成功,返回一個epoll文件描述符,在系統(tǒng)內(nèi)部創(chuàng)建一些數(shù)據(jù)結構,幫助進行已就緒的fd的管理,暫且叫做epoll模型,失敗返回-1。不用這個epoll文件描述符后要close(epollfd)。

創(chuàng)建后,用戶要告訴內(nèi)核,應當關心哪個文件描述符上的哪個事件是否就緒,select通過一個位圖結構fd_set來實現(xiàn),poll通過poll_fd來實現(xiàn)的。另外,內(nèi)核要告訴用戶,關心的哪些fd上的哪些事件event已經(jīng)就緒了。epoll還有兩個接口去做這兩個事。

Linux學習記錄——??? 高級IO(4)--- Epoll型服務器(1),Linux學習,服務器,linux,學習

epfd就是創(chuàng)建函數(shù)的返回值;op表示想做什么,有3個值,EPOLL_ADD,EPOLL_MOD,EPOLL_DEL,分別是添加、修改、刪除;fd表示哪一個fd,event表示這個fd上的哪個事件要被關心。

Linux學習記錄——??? 高級IO(4)--- Epoll型服務器(1),Linux學習,服務器,linux,學習

進行等待的接口。返回值和select,poll接口一樣,就緒的fd數(shù)量;timeout的作用和poll一樣,輸入型參數(shù),單位是毫秒ms,為0表示非阻塞,小于0表示阻塞,大于0poll在這段時間內(nèi)阻塞等待,如果一直沒有事件就緒,那么超過時間就返回0;中間兩個參數(shù)是輸出型參數(shù),操作系統(tǒng)通過這兩個告知用戶就緒的fd上就緒的事件event。

Linux學習記錄——??? 高級IO(4)--- Epoll型服務器(1),Linux學習,服務器,linux,學習

events是一個32位整數(shù),用戶輸入的是關心的事件,返回時操作系統(tǒng)通過這個整數(shù)來告訴用戶哪些fd的events事件就緒了;data的類型是一個聯(lián)合體,通常會使用prt或者fd。events有幾種取值:

EPOLLIN:表示對應的文件描述符可以讀 (包括對端SOCKET正常關閉)
EPOLLOUT:表示對應的文件描述符可以寫
EPOLLPRI:表示對應的文件描述符有緊急的數(shù)據(jù)可讀 (這里應該表示有帶外數(shù)據(jù)到來)
EPOLLERR:表示對應的文件描述符發(fā)生錯誤
EPOLLHUP:表示對應的文件描述符被掛斷
EPOLLET:將EPOLL設為邊緣觸發(fā)(Edge Triggered)模式,這是相對于水平觸發(fā)(Level Triggered)來說的
EPOLLONESHOT:只監(jiān)聽一次事件,當監(jiān)聽完這次事件之后,如果還需要繼續(xù)監(jiān)聽這個socket的話,需要
再次把這個socket加入到EPOLL隊列里

上面的就是宏。這里只關心EPOLLIN和EPOLLOUT。

TCP報頭中6個標記位中有一個代表PSH,用來提示對方應用層立刻從接收緩沖區(qū)讀取數(shù)據(jù)。但PSH并不一定能讓應用層讀取數(shù)據(jù),它的催促是讓套接字觀察的fd對應的文件里的數(shù)據(jù)處于就緒狀態(tài)。

操作系統(tǒng)可以把數(shù)據(jù)從應用層拷貝到緩沖區(qū),然后將數(shù)據(jù)交給網(wǎng)卡。當網(wǎng)卡收到數(shù)據(jù)后,網(wǎng)卡會發(fā)送硬件中斷,操作系統(tǒng)通過查看中斷向量表,知道發(fā)來的中斷號是網(wǎng)卡的,所以就知道網(wǎng)卡有了數(shù)據(jù)。select/poll都是在軟件層面去檢測是否有數(shù)據(jù)的。

CPU有對應的寄存器,寄存器是二進制序列,是一種存儲單元,由硬件電路構成。數(shù)據(jù)拷貝到CPU的硬件本質(zhì)是利用高低電頻對CPU內(nèi)的寄存器進行充放電,讓CPU的寄存器變成和內(nèi)存一樣的值。CPU和所有外設之間都有針腳間接相連。發(fā)送中斷就像是某個外設產(chǎn)生電流,從和它間接相連的針腳向寄存器充電,把數(shù)據(jù)放到寄存器中。之后網(wǎng)卡就可以發(fā)送中斷號讓CPU拷貝數(shù)據(jù)到內(nèi)存了。所以數(shù)據(jù)是可以從外設拷貝到內(nèi)存的。

用戶層往下是系統(tǒng)調(diào)用層,再往下是操作系統(tǒng),再往下就是傳輸層及以下了。當用戶層創(chuàng)建epoll時,OS會維護一個紅黑樹,開始時只有一個根節(jié)點,并且epoll還會創(chuàng)建一個就緒隊列,為空。紅黑樹的節(jié)點是結構體,里面有fd,有事件event,整個紅黑樹就是用戶告訴OS,要關心哪些fd,以及fd上的哪些事件。所以可以看出epoll_ctl本質(zhì)是對這個紅黑樹進行增刪改,比如要刪,就傳對應的fd,事件設為nullptr/NULL,那就是對紅黑樹某個節(jié)點的刪除。fd決定節(jié)點是紅還是黑,左節(jié)點還是右節(jié)點,插入到哪里。內(nèi)核中,一個數(shù)據(jù)結構對象,既可以屬于紅黑樹,也可以屬于另一個結構。

紅黑樹上只有某個fd上有對應的事件發(fā)生了,那么就把這個fd的節(jié)點接入到就緒隊列中,隊列只保存已經(jīng)準備好的fd && 對應的event。隊列每一個元素也可以是一個結構體,只取紅黑樹中已就緒節(jié)點里面的值來填充。epoll_wait接口中間兩個參數(shù)就是從就緒隊列中拿取節(jié)點,這個接口只看就緒隊列,可以以時間復雜度為O(1)的方式來檢測事件就緒,也就是隊列是否為空。

節(jié)點放入隊列實際不是將一個節(jié)點內(nèi)容拷貝到隊列節(jié)點里,而是紅黑樹節(jié)點也是隊列節(jié)點,節(jié)點就是一個結構體,結構體里可以放入表示已經(jīng)就緒的事件,放入紅黑樹相關指針信息,放入隊列相關指針信息,建立起隊列就是用這個隊列相關的指針去指向下一個節(jié)點。

當數(shù)據(jù)就緒時,操作系統(tǒng)通過網(wǎng)卡,經(jīng)過網(wǎng)絡協(xié)議棧,拷貝到每個文件的文件緩沖區(qū)中。每個節(jié)點都有回調(diào)機制,假設每個文件結構體都有一個變量,如果沒設置回調(diào),就置為空,每次操作系統(tǒng)拷貝數(shù)據(jù)到緩沖區(qū)后就去判斷一下這個變量,為空就退出,不為空就調(diào)用回調(diào)函數(shù),回調(diào)函數(shù)做的工作就是把紅黑樹上已就緒的節(jié)點放到就緒隊列中。

紅黑樹,就緒隊列,回調(diào)機制這三個整體就是epoll模型,所以epoll_create使用時就是創(chuàng)建了這些,從操作系統(tǒng)內(nèi)部到系統(tǒng)調(diào)用形成了一個體系。紅黑樹就像select/poll中的數(shù)組,但epoll這里核心的維護交由系統(tǒng)來做,不讓用戶去做。

為什么epoll_create要返回就緒fd的個數(shù),以及另外兩個接口還需要用這個數(shù)字?整個機制是由系統(tǒng)做的,接口是由進程調(diào)用的,進程在運行時,會創(chuàng)建task_struct指向文件描述符表files_struct,表里有一個數(shù)組,類型是struct file,012默認被占用,當創(chuàng)建epoll模型,操作系統(tǒng)也創(chuàng)建了一個struct file,里面有個指針指向epoll模型,這個struct file就在調(diào)用epoll接口的進程的文件描述符表中。用戶,進程,task_struct,files_struct,struct file,這是一整個路線。通過epoll_create的返回值,也就是另外兩個接口的參數(shù)epfd,兩個接口就可以找到進程維護的文件描述符表,進而找到struct file,然后找到epoll模型,就可以對紅黑樹,就緒隊列進行操作了。

epoll的紅黑樹比數(shù)組更有效率;也不需要底層在線性遍歷所有節(jié)點;上層也不需要遍歷節(jié)點只需要查看就緒隊列;用戶只需要調(diào)用接口就可以操作整個體系。

2、簡單實現(xiàn)

Main.cc

#include "EpollServer.hpp"
#include <memory>

int main()
{
    std::unique_ptr<EpollServer> svr(new EpollServer());
    svr->InitServer();
    svr->Start();
    return 0;
}

Makefile

epollserver:Main.cc
	g++ -o $@ $^ -std=c++11
.PHONY:clean
clean:
	rm -f epollserver

EpollServer.hpp中先寫基礎的

#pragma once

#include <iostream>
#include <string>
#include "Sock.hpp"
#include "log.hpp"

const static int gport = 8888;

class EpollServer
{
public:
    EpollServer(uint16_t port = gport) : port_(port)
    {}

    void InitServer()
    {
        listensock_.Socket();
        listensock_.Bind(port_);
        listensock_.Listen();
    }

    void Start()
    {
        while(true)
        {
            sleep(3);
        }
    }

    ~EpollServer()
    {}
private:
    uint16_t port_;
    Sock listensock_;
};

現(xiàn)在還不能Accept,因為還不知道底層是否有文件就緒,如果沒有,整個服務器就得阻塞了。epoll這里的思路就是把自己的權利交給epoll。要將listensock添加到epoll中,不過得先有epoll模型。

創(chuàng)建一個Epoll.hpp

#pragma once

#include <iostream>
#include <string>
#include <sys/epoll.h>

static const  int defaultepfd = -1;

class Epoller
{
public:
    Epoller():epfd_(defaultepfd)
    {}

    ~Epoller()
    {}
private:
    int epfd_;
};

完善一下Epoll模型,并初始化和析構

Epoll.hpp

#pragma once

#include <iostream>
#include <string>
#include <cstdlib>
#include <sys/epoll.h>
#include "err.hpp"
#include "log.hpp"

static const  int defaultepfd = -1;
static const int gsize = 128;

class Epoller
{
public:
    Epoller():epfd_(defaultepfd)
    {}

    void Create()
    {
        epfd_ = epoll_create(gsize);
        if(epfd_ < 0)
        {
            logMessage(Fatal, "epoll_create error, code: %d, errstring: %s", errno, strerror(errno));
            exit(EPOLL_CREAT_ERR);//err.hpp里加上這個錯誤
        }
    }

    int Fd()
    {
        return epfd_;
    }

    void Close()
    {
        if(epfd_ != defaultepfd) close(epfd_);
    }

    ~Epoller()
    {}
private:
    int epfd_;
};

EpollServer.hpp

#pragma once

#include "Epoll.hpp"
#include "Sock.hpp"
#include "log.hpp"

const static int gport = 8888;

class EpollServer
{
public:
    EpollServer(uint16_t port = gport) : port_(port)
    {}

    void InitServer()
    {
        listensock_.Socket();
        listensock_.Bind(port_);
        listensock_.Listen();
        epoller_.Create();
        logMessage(Debug, "init server success");
    }

    void Start()
    {
        //1、將listensock添加到epoll中,要先有epoll模型
        while(true)
        {
            sleep(3);
        }
    }

    ~EpollServer()
    {
        listensock_.Close();
        epoller_.Close();
    }
private:
    uint16_t port_;
    Sock listensock_;
    Epoller epoller_;
};

接下來關注事件。

Epoll.hpp

    //用戶告訴內(nèi)核要關心哪些事件
    bool AddEvent(int fd, uint32_t events)
    {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = fd;//fd就是就緒的文件描述符
        int n = epoll_ctl(epfd_, EPOLL_CTL_ADD, fd, &ev);
        if(n < 0)
        {
            logMessage(Fatal, "epoll_ctl error, code: %d, errstring: %s", errno, strerror(errno));
            return false;
        }
        return true;
    }

EpollServer.hpp

    void Start()
    {
        //1、將listensock添加到epoll中,要先有epoll模型
        bool r = epoller_.AddEvent(listensock_.Fd(), EPOLLIN);//只關心讀事件
        assert(r);//可以做別的判斷
        (void)r;
        while(true)
        {
            ;
        }
    }

然后就可以在循環(huán)中獲取事件了,使用wait。從隊列里拿數(shù)據(jù)這個過程是線性拷貝的,因為系統(tǒng)不相信用戶,所以要定義一個struct epoll_event類型的數(shù)組來接收。以及wait接口中的events參數(shù)里,由于拷貝的緣故,數(shù)據(jù)是從左到右連續(xù)有效的,而返回值 - 1就是當前最后一個有效的下標。

EpollServer.hpp

    void Start()
    {
        //1、將listensock添加到epoll中,要先有epoll模型
        bool r = epoller_.AddEvent(listensock_.Fd(), EPOLLIN);//只關心讀事件
        assert(r);//可以做別的判斷
        (void)r;
        struct epoll_event revs_[gnum];
        int timeout = 1000;
        while(true)
        {
            int n = epoller_.Wait(revs_, gnum, timeout);
            switch (n)
            {
            case 0:
                logMessage(Debug, "timeout...");
                break;
            case -1:
                logMessage(Warning, "epoll_wait failed");
                break;
            default:
                logMessage(Debug, "有%d個事件就緒了", n);
                HandlerEvents(n);//一定有數(shù)據(jù)就緒
                break;
            }
        }
    }

    void HandlerEvents(int num)
    {
        for(int i = 0; i < num; i++)
        {
            int fd = revs_[i].data.fd;
            uint32_t events = revs_[i].events;
            logMessage(Debug, "當前正在處理%d上的%s", fd, (events&EPOLLIN) ? "EPOLLIN" : "OTHER");
            if(events & EPOLLIN)//判斷讀事件就緒
            {
                if (fd == listensock_.Fd())
                {
                    // 1、新連接到來
                    std::string clientip;
                    uint16_t clientport;
                    int sock = listensock_.Accept(&clientip, &clientport);
                    if (sock < 0)
                        continue;
                    logMessage(Debug, "%s:%d 已經(jīng)連上服務器了", clientip.c_str(), clientport);
                    // 還不能recv,即使有了連接但也不知道有沒有數(shù)據(jù)
                    // 只有epoll知道具體情況,所以將sock添加到epoll中
                    bool r = epoller_.AddEvent(sock, EPOLLIN);
                    assert(r);
                    (void)r;
                }
                else // 2、讀事件
                {
                    char buffer[1024];
                    ssize_t s = recv(fd, buffer, sizeof(buffer) - 1, 0);
                    if (s > 0)
                    {
                        buffer[s - 1] = 0;//對打印格式
                        buffer[s - 2] = 0;//做一下調(diào)整
                        std::string echo = buffer;
                        echo += " [epoll server echo]\r\n";
                        std::cout << "client# " << echo << std::endl;
                        send(fd, echo.c_str(), echo.size(), 0);
                    }
                    else
                    {
                        if (s == 0)
                            logMessage(Info, "client quit ...");
                        else
                            logMessage(Warning, "recv error, client quit...");
                        close(fd);
                        //將文件描述符移除
                        //在處理異常的時候,fd必須合法才能被處理
                        epoller_.DelEvent(fd);
                    }
                }
            }
        }
    }

Epoll.hpp

    //用戶告訴內(nèi)核要關心哪些事件
    bool AddEvent(int fd, uint32_t events)
    {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = fd;//屬于用戶的數(shù)據(jù),epoll底層不對該數(shù)據(jù)做任何修改,為了給未來就緒返回
        int n = epoll_ctl(epfd_, EPOLL_CTL_ADD, fd, &ev);
        if(n < 0)
        {
            logMessage(Fatal, "epoll_ctl error, code: %d, errstring: %s", errno, strerror(errno));
            return false;
        }
        return true;
    }
    
    bool DelEvent(int fd)
    {
        return epoll_ctl(epfd_, EPOLL_CTL_DEL, fd, nullptr) == 0;
    }

    int Wait(struct epoll_event* revs, int num, int timeout)
    {

        return epoll_wait(epfd_, revs, num, timeout);
    }

讀事件處理中,我們目前無法讀到一個完整的報文。因為完整報文由應用層協(xié)議規(guī)定,我們的代碼沒有應用層協(xié)議,所以得自定義一個。

先用回調(diào)函數(shù)來處理數(shù)據(jù)

#include <functional>
using func_t = std::function<std::string (std::string)>;

public:
    EpollServer(func_t func, uint16_t port = gport) : func_(func), port_(port)
    {}
private:
    uint16_t port_;
    Sock listensock_;
    Epoller epoller_;
    struct epoll_event revs_[gnum];
    func_t func_;

讀事件處理時

                else // 2、讀事件
                {
                    char request[1024];
                    ssize_t s = recv(fd, request, sizeof(request) - 1, 0);
                    if (s > 0)
                    {
                        request[s - 1] = 0;//對打印格式
                        request[s - 2] = 0;//做一下調(diào)整
                        std::string response = func_(request);
                        send(fd, response.c_str(), response.size(), 0);
                    }
                    else
                    {
                        if (s == 0)
                            logMessage(Info, "client quit ...");
                        else
                            logMessage(Warning, "recv error, client quit...");
                        close(fd);
                        //將文件描述符移除
                        //在處理異常的時候,fd必須合法才能被處理
                        epoller_.DelEvent(fd);
                    }
                }

在Main.cc中傳入函數(shù)

#include "EpollServer.hpp"
#include <memory>

std::string echoServer(std::string r)
{
    std::string resp = r;
    resp += "[echo]\r\n";
    return resp;
}

int main()
{
    std::unique_ptr<EpollServer> svr(new EpollServer(echoServer));
    svr->InitServer();
    svr->Start();
    return 0;
}

下一篇仍然是Epoll代碼。

基本版Epoll

結束。文章來源地址http://www.zghlxwxcb.cn/news/detail-802823.html

到了這里,關于Linux學習記錄——??? 高級IO(4)--- Epoll型服務器(1)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領支付寶紅包贊助服務器費用

相關文章

  • Linux多路IO復用技術——epoll詳解與一對多服務器實現(xiàn)

    Linux多路IO復用技術——epoll詳解與一對多服務器實現(xiàn)

    本文詳細介紹了Linux中epoll模型的優(yōu)化原理和使用方法,以及如何利用epoll模型實現(xiàn)簡易的一對多服務器。通過對epoll模型的優(yōu)化和相關接口的解釋,幫助讀者理解epoll模型的工作原理和優(yōu)缺點,同時附帶代碼實現(xiàn)和圖解說明。

    2024年02月05日
    瀏覽(27)
  • 多路IO—POll函數(shù),epoll服務器開發(fā)流程

    多路IO—POll函數(shù),epoll服務器開發(fā)流程

    \\\"在計算機網(wǎng)絡編程中,多路IO技術是非常常見的一種技術。其中,Poll函數(shù)和Epoll函數(shù)是最為常用的兩種多路IO技術。這兩種技術可以幫助服務器端處理多個客戶端的并發(fā)請求,提高了服務器的性能。本文將介紹Poll和Epoll函數(shù)的使用方法,并探討了在服務器開發(fā)中使用這兩種技

    2024年02月06日
    瀏覽(18)
  • IO模型之epoll實現(xiàn)服務器客戶端收發(fā)

    IO模型之epoll實現(xiàn)服務器客戶端收發(fā)

    ?epoll.ser epoll.cri result ? ? ?

    2024年02月13日
    瀏覽(21)
  • 【TCP服務器的演變過程】使用IO多路復用器epoll實現(xiàn)TCP服務器

    【TCP服務器的演變過程】使用IO多路復用器epoll實現(xiàn)TCP服務器

    手把手教你從0開始編寫TCP服務器程序,體驗開局一塊磚,大廈全靠壘。 為了避免篇幅過長使讀者感到乏味,對【TCP服務器的開發(fā)】進行分階段實現(xiàn),一步步進行優(yōu)化升級。 本節(jié),在上一章節(jié)的基礎上,將IO多路復用機制select改為更高效的IO多路復用機制epoll,使用epoll管理每

    2024年01月17日
    瀏覽(16)
  • 多路轉(zhuǎn)接高性能IO服務器|select|poll|epoll|模型詳細實現(xiàn)

    多路轉(zhuǎn)接高性能IO服務器|select|poll|epoll|模型詳細實現(xiàn)

    那么這里博主先安利一下一些干貨滿滿的專欄啦! Linux專欄 https://blog.csdn.net/yu_cblog/category_11786077.html?spm=1001.2014.3001.5482 操作系統(tǒng)專欄 https://blog.csdn.net/yu_cblog/category_12165502.html?spm=1001.2014.3001.5482 手撕數(shù)據(jù)結構 https://blog.csdn.net/yu_cblog/category_11490888.html?spm=1001.2014.3001.5482 去倉庫獲

    2024年02月15日
    瀏覽(25)
  • 手撕測試tcp服務器效率工具——以epoll和io_uring對比為例

    手撕測試tcp服務器效率工具——以epoll和io_uring對比為例

    服務器的性能測試主要包括2部分: 并發(fā)量。能容納多大的連接 效率。在不崩壞的情況下能對報文的處理效率。 本文主要進行效率測試,看看基于epoll模型和io_uring模型的tcp服務器,誰的效率更高。 測試思路 客戶端(一個或多個)大量地向服務器發(fā)送報文,測試服務器的處理

    2024年01月18日
    瀏覽(23)
  • 【Linux】高級IO --- 多路轉(zhuǎn)接,select,poll,epoll

    【Linux】高級IO --- 多路轉(zhuǎn)接,select,poll,epoll

    所有通過捷徑所獲取的快樂,無論是金錢、性還是名望,最終都會給自己帶來痛苦 1. 后端服務器最常用的網(wǎng)絡IO設計模式其實就是Reactor,也稱為反應堆模式,Reactor是單進程,單線程的,但他能夠處理多客戶端向服務器發(fā)起的網(wǎng)絡IO請求,正因為他是單執(zhí)行流,所以他的成本就

    2024年02月09日
    瀏覽(25)
  • Linux學習記錄——?? 高級IO(1)

    Linux學習記錄——?? 高級IO(1)

    其它IO類型的實現(xiàn)在這篇之后的三篇 input,output。調(diào)用read或recv接口時,如果對方長時間不向我方接收緩沖區(qū)拷貝數(shù)據(jù),我們的進程就只能阻塞,這是讀取條件不滿足。阻塞的時間成本最后會體現(xiàn)在用戶上。因此可以說,IO = 等 + 數(shù)據(jù)拷貝。高效IO則是單位事件內(nèi),等的比重越

    2024年01月21日
    瀏覽(22)
  • Linux網(wǎng)絡編程:多路I/O轉(zhuǎn)接服務器(select poll epoll)

    Linux網(wǎng)絡編程:多路I/O轉(zhuǎn)接服務器(select poll epoll)

    文章目錄: 一:select 1.基礎API? select函數(shù) 思路分析 select優(yōu)缺點 2.server.c 3.client.c 二:poll 1.基礎API? poll函數(shù)? poll優(yōu)缺點 read函數(shù)返回值 突破1024 文件描述符限制 2.server.c 3.client.c 三:epoll 1.基礎API epoll_create創(chuàng)建? ?epoll_ctl操作? epoll_wait阻塞 epoll實現(xiàn)多路IO轉(zhuǎn)接思路 epoll優(yōu)缺點

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

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

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

    2024年02月20日
    瀏覽(35)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領取紅包

二維碼2

領紅包