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

linux中epoll+socket實戰(zhàn)

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

參考

Linux Epoll使用詳解
利用Socket網(wǎng)絡(luò)編程實現(xiàn)TCP時遇到的無法立刻建立第二次連接傳輸數(shù)據(jù)的問題
TCP面試常見題:time_wait狀態(tài)產(chǎn)生的原因,危害,如何避免
計算機網(wǎng)絡(luò) | C++實現(xiàn)TCP/UDP的socket通信
愛編程的大丙

前言

在linux的網(wǎng)絡(luò)編程中,很長的時間都在使用select來做事件觸發(fā)。在linux新的內(nèi)核中,有了一種替換它的機制,就是epoll。

相比于select,epoll最大的好處在于它不會隨著監(jiān)聽fd數(shù)目的增長而降低效率。因為在內(nèi)核中的select實現(xiàn)中,它是采用輪詢來處理的,輪詢的fd數(shù)目越多,自然耗時越多。并且,在linux/posix_types.h頭文件有這樣的聲明:

#define __FD_SETSIZE    1024

表示select最多同時監(jiān)聽1024個fd,當(dāng)然,可以通過修改頭文件再重編譯內(nèi)核來擴大這個數(shù)目,但這似乎并不治本。

linux中epoll+socket實戰(zhàn)

案例

  • 單線程epoll:redis
    純粹內(nèi)容操作,只有一個epoll,沒有多線程加鎖以及切換
  • 多線程epoll:nettyserver
  • 多核epoll:ntyco
  • 多進程epoll:nginx

一、epoll的基本使用

epoll的接口非常簡單,一共就三個函數(shù):

  • epoll_create:創(chuàng)建一個epoll的句柄 ,相當(dāng)于聘請了一個快讀員
  • epoll_ctl:epoll的事件注冊函數(shù),相當(dāng)于快遞員對住戶的增刪改查
  • epoll_wait:等待事件的產(chǎn)生,相當(dāng)于快讀員等待不停的收發(fā)快遞

首先是epoll_create函數(shù):

int epoll_create (int __size)

它只有一個參數(shù),用來告訴系統(tǒng)這個監(jiān)聽的數(shù)目一共有多大,但這個參數(shù)不同于select中的第一個參數(shù)。而是我們真實要監(jiān)聽的文件數(shù)量(事實上,在新版的Linux內(nèi)核中,該值已經(jīng)被忽略,只要大于0即可)

需要注意的是,當(dāng)創(chuàng)建好epoll句柄后,它就是會占用一個fd值,所以在使用完epoll后,必須調(diào)用close()關(guān)閉

然后是epoll_ctl函數(shù):

int epoll_ctl (int __epfd, int __op, int __fd,epoll_event *__event)

它不同與select是在監(jiān)聽事件時告訴內(nèi)核要監(jiān)聽什么類型的事件,而是在這里先注冊要監(jiān)聽的事件類型。

  • 第一個參數(shù)是epoll_create的返回值
  • 第二個參數(shù)表示要執(zhí)行的動作,有以下幾種參數(shù)可填:
    EPOLL_CTL_ADD:注冊新的文件標識符到epfd中
    EPOLL_CTL_MOD:修改已經(jīng)注冊的fd的監(jiān)聽事件
    EPOLL_CTL_DEL:從epfd中刪除一個文件標識符
  • 第三個參數(shù)是需要監(jiān)聽的文件標識符
  • 第四個參數(shù)是告訴內(nèi)核需要監(jiān)聽什么事,

結(jié)構(gòu)體epoll_event結(jié)構(gòu)如下:

typedef union epoll_data
{
  void *ptr;
  int fd;
  uint32_t u32;
  uint64_t u64;
} epoll_data_t;

struct epoll_event
{
  uint32_t events;	/* Epoll events */
  epoll_data_t data;	/* User data variable */
} __EPOLL_PACKED;

其中events參數(shù)可以是以下幾個宏的集合:

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

而data則一般用于攜帶附加數(shù)據(jù),比如網(wǎng)絡(luò)編程中的套接字文件的fd

最后是epoll_wait函數(shù):

TCP接收到事件時會回調(diào)觸發(fā)epoll_wait 中事件

int epoll_wait (int __epfd, struct epoll_event *__events,int __maxevents, int __timeout)
  • 第一個參數(shù)就是前面epoll_create函數(shù)的返回值
  • 參數(shù)events用來從系統(tǒng)內(nèi)核得到事件的集合
  • maxevents告知內(nèi)核這個events有多大,不能大于創(chuàng)建epoll_create()時的size
  • 參數(shù)timeout是超時時間(毫秒,0會立即返回,-1將永久阻塞(直到有事件發(fā)生)
  • 該函數(shù)返回需要處理的事件數(shù)目,如返回0表示已超時。

關(guān)于ET(邊沿觸發(fā))、LT(水平觸發(fā))兩種工作模式可以得出這樣的結(jié)論:

ET模式僅當(dāng)狀態(tài)發(fā)生變化的時候才獲得通知,這里所謂的狀態(tài)的變化并不包括緩沖區(qū)中還有未處理的數(shù)據(jù),也就是說,如果要采用ET模式,需要一直read/write直到出錯為止,很多人反映為什么采用ET模式只接收了一部分數(shù)據(jù)就再也得不到通知了,大多因為這樣;而LT模式是只要有數(shù)據(jù)沒有處理就會一直通知下去的.

二、使用

前提先包含一個頭文件:

#include <sys/epoll.h> 

然后通過create_epoll來創(chuàng)建一個epoll,其參數(shù)為你epoll所支持的最大數(shù)量(已忽略)。

這個函數(shù)會返回一個新的epoll句柄,之后的所有操作將通過這個句柄來進行操作。在用完之后,記得用close來關(guān)閉這個創(chuàng)建出來的epoll句柄。

之后在你的網(wǎng)絡(luò)主循環(huán)里面,每次調(diào)用epoll_wait來查詢所有的網(wǎng)絡(luò)接口,看哪一個可以讀,哪一個可以寫了。基本的語法為:

nfds = epoll_wait(kdpfd, events, maxevents, -1);

其中kdpfd為用epoll_create創(chuàng)建之后的句柄
events是一個epoll_event*的指針,當(dāng)epoll_wait這個函數(shù)操作成功之后,epoll_events里面將儲存所有的讀寫事件。
max_events是當(dāng)前需要監(jiān)聽的所有socket句柄數(shù)。
最后一個timeout是 epoll_wait的超時,為0的時候表示馬上返回,為-1的時候表示一直等下去,直到有事件發(fā)生,為任意正整數(shù)的時候表示等這么長的時間,如果一直沒有事件,則等待。
一般如果網(wǎng)絡(luò)主循環(huán)是單獨的線程的話,可以用-1來等,這樣可以保證一些效率,如果是和主邏輯在同一個線程的話,則可以用0來保證主循環(huán)的效率。

epoll_wait函數(shù)之后應(yīng)該是一個循環(huán),遍利所有的事件。

代碼簡易實現(xiàn)


#include<sys/socket.h> // socket依賴
#include<arpa/inet.h> // socket依賴
#include <unistd.h> // close依賴
#include<sys/epoll.h>
#include<cstring>
#include<iostream>

#include "log.h"
using namespace std;

#define MAX_LISTEN_SOCKET 10
#define SOCKET_PORT 5000

int main(){

    int sockfd = 0;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    LOG_INFO("監(jiān)聽套接字文件描述符:%d\n", sockfd);

    sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(SOCKET_PORT);
	// addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	addr.sin_addr.s_addr = htons(INADDR_ANY);

	// 一般在一個端口釋放后需要等一段時間才能重新啟用,因此需要借助SO_REUSEADDR來使端口重新啟用。解決服務(wù)端異常退出之后,再次啟動服務(wù)端,客戶端無法使用同一個端口連接socket的問題
	int out = 1;
    int ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &out, sizeof(out));
	if (ret < 0) {
		LOG_ERROR("setsockopt");
		return -1;
	}
	ret = bind(sockfd, (sockaddr*)&addr, sizeof(addr));
	if (ret == -1) {
		LOG_ERROR("綁定失?。n");
		return -1;
	}
    ret = listen(sockfd, 5);
    if (ret == -1) {
		LOG_ERROR("監(jiān)聽失??!\n");
		return -1;
	}
	sockaddr_in cliAddr;
	socklen_t len = sizeof(cliAddr);


    // 創(chuàng)建epoll ,int epoll_create(int size); size參數(shù) 相當(dāng)于提供給內(nèi)核一個提示,當(dāng)前需要監(jiān)聽的fd個數(shù)
    int fdEp = epoll_create(MAX_LISTEN_SOCKET);
	epoll_event eve;
	eve.data.fd = sockfd;
	eve.events = EPOLLIN ;

    // 注冊事件
	ret = epoll_ctl(fdEp, EPOLL_CTL_ADD, sockfd, &eve);
    if(ret == -1) {
        LOG_ERROR("epoll注冊失敗\n");
        close(sockfd);
		return -1;
    }
	LOG_INFO("開始監(jiān)聽!");
    epoll_event events[MAX_LISTEN_SOCKET];
    while (1) {
		/* timeout 500 epoll_wait (int __epfd, struct epoll_event *__events, int __maxevents, int __timeout);
		*   __epfd:由epoll_create 生成的epoll專用的文件描述符 
			__events:分配好的epoll_event結(jié)構(gòu)體數(shù)組 用于接收fd對象的緩沖區(qū)
			__maxevents:每次能夠處理的事件數(shù) 這一次調(diào)用可以接收多少準備好的fd對象,通常設(shè)置為events參數(shù)的長度
			__timeout:如果沒有準備好的事件對象,那么等待多久返回,-1阻塞,0非阻塞
			返回值:返回events緩沖區(qū)中有效的fd個數(shù),也即準備好事件的fd個數(shù)
		*/
		int eventCount = epoll_wait(fdEp, events, MAX_LISTEN_SOCKET, 500);
        if (eventCount == -1) {
			LOG_ERROR("select 出錯!\n");
			break;
		}else if (eventCount == 0) {
			continue;
		}
		LOG_INFO("監(jiān)聽到事件數(shù)量:%d\n",eventCount);
        for (int i = 0; i < eventCount; i++) {
			// 如果是服務(wù)器fd并且是讀事件,則接收連接
			if (events[i].data.fd == sockfd) {
				// 是否讀事件
				if(events[i].events & EPOLLIN){
					int clisock = accept(sockfd, (sockaddr*)&cliAddr, &len);
					if (clisock == -1) {
						LOG_ERROR("接收客戶端錯誤\n");
						continue;
					}else{
						LOG_INFO("接收到客戶端連接");
					}

					eve.data.fd = clisock;
					eve.events = EPOLLIN;
					epoll_ctl(fdEp, EPOLL_CTL_ADD, clisock, &eve);
				}else{
					LOG_INFO("服務(wù)器其他事件");
				}

			}
			else {
				// 對非服務(wù)器socket進行處理
				if (events[i].events & EPOLLIN) {
					char buf[0xFF]{};
					size_t len = recv(events[i].data.fd, buf, 0xFF, 0);
					if (len < 0) {
						LOG_ERROR("客戶端異常!");
						epoll_ctl(fdEp, EPOLL_CTL_DEL, events[i].data.fd, NULL);
						close(events[i].data.fd);
						break;
					}else if (len == 0) {
						LOG_INFO("客戶端已經(jīng)斷開連接!");
						epoll_ctl(fdEp, EPOLL_CTL_DEL, events[i].data.fd, NULL);
						close(events[i].data.fd);
						break;
					}else{
						LOG_INFO("客戶端接收到數(shù)據(jù):%s",buf);
					}
					send(events[i].data.fd, buf, len, 0);
				}
				else if(events[i].events & EPOLLOUT) {
					LOG_INFO("客戶端 EPOLLOUT");
				}
				else {
					LOG_INFO("客戶端其他事件");
				}
				
			}
		}
    }
    close(fdEp);
	close(sockfd);
    return 0;
}

三、注意問題

因TIME_WAIT導(dǎo)致的客戶端斷開之后無法立馬重連

問題描述

在測試時發(fā)現(xiàn),當(dāng)客戶端和服務(wù)器端建立第一次連接并成功發(fā)送數(shù)據(jù)后,關(guān)閉連接,想要立刻建立第二次連接發(fā)送數(shù)據(jù)時,客戶端會無法再次連接。大約2分鐘(MSL)之后才可以重新連接

time_wait狀態(tài)產(chǎn)生的原因

  • 1)為實現(xiàn)TCP全雙工連接的可靠釋放
    由TCP狀態(tài)變遷圖可知,假設(shè)發(fā)起主動關(guān)閉的一方(client)最后發(fā)送的ACK在網(wǎng)絡(luò)中丟失,由于TCP協(xié)議的重傳機制,執(zhí)行被動關(guān)閉的一方(server)將會重發(fā)其FIN,在該FIN到達client之前,client必須維護這條連接狀態(tài),也就說這條TCP連接所對應(yīng)的資源(client方的local_ip,local_port)不能被立即釋放或重新分配,直到另一方重發(fā)的FIN達到之后,client重發(fā)ACK后,經(jīng)過2MSL時間周期沒有再收到另一方的FIN之后,該TCP連接才能恢復(fù)初始的CLOSED狀態(tài)。如果主動關(guān)閉一方不維護這樣一個TIME_WAIT狀態(tài),那么當(dāng)被動關(guān)閉一方重發(fā)的FIN到達時,主動關(guān)閉一方的TCP傳輸層會用RST包響應(yīng)對方,這會被對方認為是有錯誤發(fā)生,然而這事實上只是正常的關(guān)閉連接過程,并非異常。

  • 2)為使舊的數(shù)據(jù)包在網(wǎng)絡(luò)因過期而消失
    為說明這個問題,我們先假設(shè)TCP協(xié)議中不存在TIME_WAIT狀態(tài)的限制,再假設(shè)當(dāng)前有一條TCP連接:(local_ip, local_port, remote_ip,remote_port),因某些原因,我們先關(guān)閉,接著很快以相同的四元組建立一條新連接。本文前面介紹過,TCP連接由四元組唯一標識,因此,在我們假設(shè)的情況中,TCP協(xié)議棧是無法區(qū)分前后兩條TCP連接的不同的,在它看來,這根本就是同一條連接,中間先釋放再建立的過程對其來說是“感知”不到的。這樣就可能發(fā)生這樣的情況:前一條TCP連接由local peer發(fā)送的數(shù)據(jù)到達remote peer后,會被該remot peer的TCP傳輸層當(dāng)做當(dāng)前TCP連接的正常數(shù)據(jù)接收并向上傳遞至應(yīng)用層(而事實上,在我們假設(shè)的場景下,這些舊數(shù)據(jù)到達remote peer前,舊連接已斷開且一條由相同四元組構(gòu)成的新TCP連接已建立,因此,這些舊數(shù)據(jù)是不應(yīng)該被向上傳遞至應(yīng)用層的),從而引起數(shù)據(jù)錯亂進而導(dǎo)致各種無法預(yù)知的詭異現(xiàn)象。作為一種可靠的傳輸協(xié)議,TCP必須在協(xié)議層面考慮并避免這種情況的發(fā)生,這正是TIME_WAIT狀態(tài)存在的第2個原因。

  • 3)總結(jié)
    具體而言,local peer主動調(diào)用close后,此時的TCP連接進入TIME_WAIT狀態(tài),處于該狀態(tài)下的TCP連接不能立即以同樣的四元組建立新連接,即發(fā)起active close的那方占用的local port在TIME_WAIT期間不能再被重新分配。由于TIME_WAIT狀態(tài)持續(xù)時間為2MSL,這樣保證了舊TCP連接雙工鏈路中的舊數(shù)據(jù)包均因過期(超過MSL)而消失,此后,就可以用相同的四元組建立一條新連接而不會發(fā)生前后兩次連接數(shù)據(jù)錯亂的情況。

原因分析

  • 1、TCP的可靠連接
    眾所周知,TCP是一種可靠的連接,而斷開連接需要“四次揮手”,為保證傳輸?shù)目煽啃?,需要有一個階段來保證能夠?qū)Τ鲥e或丟失的數(shù)據(jù)包進行重發(fā),那么這個階段就是TIME_WAIT狀態(tài)。

  • 2、允許老的重復(fù)分解在網(wǎng)絡(luò)中消失
    關(guān)于這句話,看起來可能沒那么容易理解,按通俗的話來講就是:在第一次使用bind()函數(shù)綁定端口后,再次啟動程序,導(dǎo)致地址復(fù)用,從而bind()函數(shù)error。

  • MSL(Maximum Segment Lifetime)最大報文生存時間
    每個TCP實現(xiàn)必須選擇一個MSL。它是任何報文段被丟棄前在網(wǎng)絡(luò)內(nèi)的最長時間。這個時間是有限的,因為TCP報文段以IP數(shù)據(jù)報在網(wǎng)絡(luò)內(nèi)傳輸,而IP數(shù)據(jù)報則有限制其生存時間的TTL時間。RFC 793指出MSL為2分鐘,現(xiàn)實中常用30秒或1分鐘。

  • 2MSL
    當(dāng)TCP執(zhí)行主動關(guān)閉,并發(fā)出最后一個ACK,該鏈接必須在TIME_WAIT狀態(tài)下停留的時間為2MSL。這樣可以(1)讓TCP再次發(fā)送最后的ACK以防這個ACK丟失(被動關(guān)閉的一方超時并重發(fā)最后的FIN);保證TCP的可靠的全雙工連接的終止。(2)允許老的重復(fù)分節(jié)在網(wǎng)絡(luò)中消失。參考文章《unix網(wǎng)絡(luò)編程》(3)TCP連接的建立和終止 在TIME_WAIT狀態(tài) 時兩端的端口不能使用,要等到2MSL時間結(jié)束才可繼續(xù)使用。當(dāng)連接處于2MSL等待階段時任何遲到的報文段都將被丟棄。不過在實際應(yīng)用中可以通過設(shè)置 SO_REUSEADDR選項達到不必等待2MSL時間結(jié)束再使用此端口。

有了這個思路,那么如果能夠讓一個端口在短時間內(nèi)連續(xù)使用,我們的問題不就可以解決了嗎?

SO_REUSEADDR,用于對TCP套接字處于TIME_WAIT狀態(tài)下的socket,當(dāng)你想要在端口被釋放后立即可以使用,那么應(yīng)該在bind之前調(diào)用SO_REUSEADDR。

int ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &out, sizeof(out));

總結(jié):一般在一個端口釋放后需要等一段時間才能重新啟用,因此需要借助SO_REUSEADDR來使端口重新啟用。

四、socket

緩沖區(qū)大小

建立一個socket,通過getsockopt獲取緩沖區(qū)的值如下:
發(fā)送緩沖區(qū)大?。?code>SNDBufSize = 16384
接收緩沖區(qū)大?。?code>RCVBufSize = 87380
通過代碼設(shè)置緩存區(qū)

bool Socket::set_send_buffer(int size)
{
    int buff_size = size;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_SNDBUF, &buff_size, sizeof(buff_size)) < 0)
    {
        LOG_ERROR("socket set send buffer error: errno=%d errstr=%s", errno, strerror(errno));
        return false;
    }
    return true;
}

bool Socket::set_recv_buffer(int size)
{
    int buff_size = size;
    if (setsockopt(m_sockfd, SOL_SOCKET, SO_RCVBUF, &buff_size, sizeof(buff_size)) < 0)
    {
        LOG_ERROR("socket set recv buffer error: errno=%d errstr=%s", errno, strerror(errno));
        return false;
    }
    return true;
}

如果接收緩存區(qū)設(shè)置過小,比如設(shè)置10,會導(dǎo)致recv循環(huán)讀取返回值為-1,此時socket并沒有斷開,循環(huán)繼續(xù)是可以讀取到數(shù)據(jù)的,但是會導(dǎo)致比如上傳文件時速度變慢,所以緩存區(qū)大小建議默認或者設(shè)置大一些文章來源地址http://www.zghlxwxcb.cn/news/detail-444965.html

set_keep_alive

set_linger

/* 優(yōu)雅關(guān)閉: 直到所剩數(shù)據(jù)發(fā)送完畢或超時 */

到了這里,關(guān)于linux中epoll+socket實戰(zhàn)的文章就介紹完了。如果您還想了解更多內(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īng)查實,立即刪除!

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

相關(guān)文章

  • 02-Linux-IO多路復(fù)用之select、poll和epoll詳解

    02-Linux-IO多路復(fù)用之select、poll和epoll詳解

    前言: 在linux系統(tǒng)中,實際上所有的 I/O 設(shè)備都被抽象為了文件這個概念,一切皆文件,磁盤、網(wǎng)絡(luò)數(shù)據(jù)、終端,甚至進程間通信工具管道 pipe 等都被當(dāng)做文件對待。 在了解多路復(fù)用 select、poll、epoll 實現(xiàn)之前,我們先簡單回憶復(fù)習(xí)以下兩個概念: 一、什么是多路復(fù)用: 多路

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

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

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

    2024年02月14日
    瀏覽(16)
  • Linux之epoll理解

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

    2024年02月07日
    瀏覽(9)
  • Linux_epoll

    Linux_epoll

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

    2024年02月08日
    瀏覽(10)
  • linux--epoll

    linux--epoll

    參考文獻 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日
    瀏覽(12)
  • Linux多路IO復(fù)用:epoll

    Linux多路IO復(fù)用:epoll

    ? ? ? ? epoll是為克服select、poll每次監(jiān)聽都需要在用戶、內(nèi)核空間反復(fù)拷貝,以及需要用戶程序自己遍歷發(fā)現(xiàn)有變化的文件描述符的缺點的多路IO復(fù)用技術(shù)。 epoll原理 創(chuàng)建內(nèi)核空間的紅黑樹; 將需要監(jiān)聽的文件描述符上樹; 內(nèi)核監(jiān)聽紅黑樹上文件描述符的變化; 返回有變化

    2024年02月04日
    瀏覽(22)
  • linux poll,epoll,select的區(qū)別

    epoll中紅黑樹的作用? 紅黑樹(rbtree)、以及epoll的實現(xiàn)原理_epoll 紅黑樹_For Nine的博客-CSDN博客 紅黑樹和epoll_wait的關(guān)系? epoll_wait/就緒list和紅黑樹的關(guān)系 - 知乎 其他區(qū)別: 1. select 在linux內(nèi)核中限制了能監(jiān)聽的數(shù)目上限。32位是1024,64位是2048 2. poll是將監(jiān)聽的對象改成了鏈表

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

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

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

    2024年02月09日
    瀏覽(26)
  • Linux網(wǎng)絡(luò)編程(epoll的ET模式和LT模式)

    本篇文章主要來講解epoll的ET模式和LT模式,epoll中有兩種模式可以選擇一種是ET模式(邊緣觸發(fā)模式),另一種是LT模式(水平觸發(fā)模式) 在水平觸發(fā)模式下,當(dāng)一個文件描述符上的I/O事件就緒時,epoll會立即通知應(yīng)用程序,然后應(yīng)用程序可以對就緒事件進行處理。即,只要文件描述

    2024年02月12日
    瀏覽(24)
  • 高性能網(wǎng)絡(luò)設(shè)計秘笈:深入剖析Linux網(wǎng)絡(luò)IO與epoll

    本文分享自華為云社區(qū)《高性能網(wǎng)絡(luò)設(shè)計秘笈:深入剖析Linux網(wǎng)絡(luò)IO與epoll》,作者: Lion Long 。 epoll是Linux內(nèi)核中一種可擴展的IO事件處理機制,可替代select和poll的系統(tǒng)調(diào)用。處理百萬級并發(fā)訪問性能更佳。 (1)?文件描述符越多,性能越差。?單個進程中能夠監(jiān)視的文件描述

    2024年02月16日
    瀏覽(34)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包