精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux內核IO多路復用之epoll簡介

冬至配餃子 ? 來源:嵌入式軟件開發交流 ? 作者:young ? 2022-08-08 17:53 ? 次閱讀

epoll簡介

epoll是Linux內核為處理大量句柄而改進的poll,它能顯著的減少程序在大量并發連接中只有少量活躍的情況下的系統CPU利用率。

epoll的工作方式

LT(level triggered):水平觸發,缺省方式,在這種方式中,內核告訴我們一個文件描述符是否就緒了,如果就緒了,就可以對描述符進行IO操作。如果不做任何操作,內核還是會繼續通知。

ET(edge-triggered):邊沿觸發,在這種方式下,當描述符從未就緒變為就緒狀態時,內核通知應用。但是如果一直不對這個描述符做IO操作,內核不會再發送通知。

區別: 邊沿觸發僅觸發一次,水平觸發會一直觸發。

epoll相關函數

epoll主要有epoll_create, epoll_ctl, epoll_wait 3個系統調用。

epoll_create

int epoll_create(int size)

創建一個epoll的句柄。自從linux2.6.8之后,size參數是被忽略的。

epoll_ctl

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)

epoll的事件注冊函數,在這里先注冊要監聽的事件類型。

epfd: epoll句柄

op: 表示動作,有如下三個動作:

EPOLL_CTL_ADD:注冊新的fd到epfd中;
EPOLL_CTL_MOD:修改已經注冊的fd的監聽事件;
EPOLL_CTL_DEL:從epfd中刪除一個fd;
fd: 要監聽的描述符。

event: 要監聽的事件,struct epoll_event結構如下:

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;

events可設置的值如下:

EPOLLIN :表示對應的文件描述符可以讀;
EPOLLOUT:表示對應的文件描述符可以寫;
EPOLLERR:表示對應的文件描述符發生錯誤;
EPOLLHUP:表示對應的文件描述符被掛斷;
EPOLLET:將EPOLL設為邊緣觸發(Edge Triggered)模式
EPOLLONESHOT:只監聽一次事件,當監聽結束之后,要繼續監聽的話,需要再次加入到EPOLL隊列里

epoll_wait

int epoll_wait(int epfd, structepoll_event * events, int maxevents, int timeout)
等待事件的到來。

events: 分配好的epoll_event結構體數組,epoll將會把發生的事件賦值到events數組中。

maxevents: events的大小。

timeout: 超時時間(毫秒,0會立即返回,-1將是永久阻塞)。

如果函數調用成功,返回對應I/O上已準備好的文件描述符數目,如返回0表示已超時。

使用例子


/* net_epoll.c */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define PORT 4321
#define MAX_QUE_CONN_NM 5
#define EPOLL_SIZE 10 //epoll監聽的客戶端的最大數目,Linux2.6.8之后該參數可以忽略
#define BUFFER_SIZE 1024

int main()
{
struct sockaddr_in server_sockaddr, client_sockaddr;
int sin_size, count;
int epfd;
struct epoll_event ev, events[EPOLL_SIZE];
int event_cnt;
int sockfd, client_fd;
char buf[BUFFER_SIZE];
//創建socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}
//設置IP,端口
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
server_sockaddr.sin_addr.s_addr = INADDR_ANY; //任意地址,也就是表示本機的所有IP
bzero(&(server_sockaddr.sin_zero), 8);
int i = 1;/* 允許重復使用本地地址與套接字進行綁定 */
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
//綁定
if (bind(sockfd, (struct sockaddr *)&server_sockaddr,
sizeof(struct sockaddr)) == -1)
{
perror("bind");
exit(1);
}
//開始監聽
if(listen(sockfd, MAX_QUE_CONN_NM) == -1)
{
perror("listen");
exit(1);
}

printf("listening....\n");

//創建一個epoll描述符,并將監聽socket加入epoll
if((epfd = epoll_create(EPOLL_SIZE)) == -1)
{
perror("epoll_create");
exit(1);
}
else
{
ev.events = EPOLLIN | EPOLLOUT | EPOLLET; //讀寫事件,邊沿觸發
ev.data.fd = sockfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
}

while(1)
{
sin_size = sizeof(struct sockaddr_in);
memset(buf, 0, sizeof(buf));
/*調用 epoll_wait()等待事件到來*/
if ((event_cnt = epoll_wait(epfd, events, EPOLL_SIZE, -1)) <= 0)
{
perror("epoll_wait");
}

for (i = 0; i < event_cnt; i++)
{
//判斷來事件的是否是監聽連接的socket
if (events[i].data.fd == sockfd)
{ /* 服務端接收客戶端的連接請求 */
if ((client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, (socklen_t *)&sin_size))== -1)
{
perror("accept");
exit(1);
}
//將新連接的socket放進去
ev.data.fd = client_fd;
epoll_ctl(epfd, EPOLL_CTL_ADD, client_fd, &ev);
printf("New connection from %d(socket)\n", client_fd);
}
else /* 處理從客戶端發來的消息 */
{
if ((count = recv(events[i].data.fd, buf, BUFFER_SIZE, 0)) > 0)
{
printf("Received a message from %d: %s\n",
events[i].data.fd, buf);
}
else
{
close(events[i].data.fd);
ev.data.fd = events[i].data.fd;
epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, &ev);
printf("Client %d(socket) has left\n", events[i].data.fd);
}
}
} /* end of for fd*/
} /* end if while while*/

close(sockfd);
exit(0);
}

總結

epoll的優點是支持大數目的描述符,IO效率不隨描述符數目增加而線性下降。所以在高并發網絡中應用比較多,一般是在服務端。



審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • cpu
    cpu
    +關注

    關注

    68

    文章

    10825

    瀏覽量

    211150
  • LINUX內核
    +關注

    關注

    1

    文章

    316

    瀏覽量

    21618
  • epoll
    +關注

    關注

    0

    文章

    28

    瀏覽量

    2947
收藏 人收藏

    評論

    相關推薦

    一節課了解IO多路復用-2021.8.31-大海老師 - 第1節 #硬聲創作季

    IO多路復用
    充八萬
    發布于 :2023年09月01日 21:27:46

    一節課了解IO多路復用-2021.8.31-大海老師 - 第8節 #硬聲創作季

    IO多路復用
    充八萬
    發布于 :2023年09月01日 21:33:38

    一節課了解IO多路復用-2021.8.31-大海老師 - 第9節 #硬聲創作季

    IO多路復用
    充八萬
    發布于 :2023年09月01日 21:34:29

    一節課了解IO多路復用-2021.8.31-大海老師 - 第13節 #硬聲創作季

    IO多路復用
    充八萬
    發布于 :2023年09月01日 21:37:50

    多路復用技術

    2.3  多路復用技術2.3.1  頻分多路復用2.3.2  時分多路復用2.3.3  波分多路復用2.3.4  碼分
    發表于 06-27 21:46 ?0次下載

    多路復用多路復用總線轉換橋的設計與實現

    多路復用多路復用總線轉換橋的設計與實現 提出了一種新穎的非多路復用總線與多路復用總線的轉換接口電路。以兩種總線的典型代表芯片TMS
    發表于 03-28 15:14 ?943次閱讀
    非<b class='flag-5'>多路復用</b>與<b class='flag-5'>多路復用</b>總線轉換橋的設計與實現

    復用器的多路復用

    復用器的多路復用  多路復用
    發表于 01-07 14:27 ?1184次閱讀

    Linuxepoll IO多路復用機制

    epollLinux內核中的一種可擴展IO事件處理機制,最早在 Linux 2.5.44內核
    發表于 05-16 16:07 ?699次閱讀
    <b class='flag-5'>Linux</b>中<b class='flag-5'>epoll</b> <b class='flag-5'>IO</b><b class='flag-5'>多路復用</b>機制

    深度剖析Linuxepoll機制

    Linux 系統之中有一個核心武器:epoll 池,在高并發的,高吞吐的 IO 系統中常常見到 epoll 的身影。 IO
    的頭像 發表于 07-29 10:52 ?1393次閱讀

    網絡IO的弊端以及多路復用IO的優勢

    為了講多路復用,當然還是要跟風,采用鞭尸的思路,先講講傳統的網絡 IO 的弊端,用拉踩的方式捧起多路復用 IO 的優勢。 為了方便理解,以下所有代碼都是偽代碼,知道其表達的意思即可。
    的頭像 發表于 08-25 18:01 ?2867次閱讀
    網絡<b class='flag-5'>IO</b>的弊端以及<b class='flag-5'>多路復用</b><b class='flag-5'>IO</b>的優勢

    linux異步io框架iouring應用

    完善的異步IO(網絡IO、磁盤IO)機制。 在網絡編程中,我們通常使用epoll IO多路復用
    的頭像 發表于 11-08 15:39 ?646次閱讀
    <b class='flag-5'>linux</b>異步<b class='flag-5'>io</b>框架iouring應用

    epoll來實現多路復用

    本人用epoll來實現多路復用epoll觸發模式有兩種: ET(邊緣模式) LT(水平模式) LT模式 是標準模式,意味著每次epoll_wait()返回后,事件處理后,如果之后還有
    的頭像 發表于 11-09 10:15 ?485次閱讀
    用<b class='flag-5'>epoll</b>來實現<b class='flag-5'>多路復用</b>

    IO多路復用基本概念

    一、IO多路復用基本概念 select、poll、epoll都是IO多路復用的機制。IO
    的頭像 發表于 11-10 16:34 ?1361次閱讀
    <b class='flag-5'>IO</b><b class='flag-5'>多路復用</b>基本概念

    什么是io多路復用IO多路復用的優缺點

    IO多路復用是一種同步IO模型,它允許單個進程/線程同時處理多個IO請求。具體來說,一個進程/線程可以監視多個文件句柄,一旦某個文件句柄就緒,就能夠通知應用程序進行相應的讀寫操作。在沒
    的頭像 發表于 01-18 15:48 ?1593次閱讀

    Linux--IO多路復用(select,poll,epoll)

    :等待數據到達:程序等待數據從IO設備傳輸到內核空間。在這個階段,IO多路復用的系統調用會阻塞,直到至少有一個描述符準備好進行IO操作。數據
    的頭像 發表于 11-06 16:13 ?159次閱讀