亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 操作系統 > 正文

Event Poll epoll 詳解

2024-06-28 13:23:31
字體:
來源:轉載
供稿:網友
Event Poll epoll 詳解

由于poll()和select()的局限,2.6內核引入了event poll(epoll)機制。雖然稍微復雜,但是epoll解決了它們共有的基本性能問題,并增加了一些新的特性。

poll()和select()每次調用都需要所有被監聽的文件描述符。內核必須遍歷所有被監視的文件描述符。當這個表變得很大時,成千上百的文件描述符,每次調用時的遍歷就成為了明顯的瓶頸。

1、創建一個新的epoll實例

使用epoll_create()或者epoll_cerate1()創建一個epoll上下文。這里epoll_cerate1()是epoll_cerate()的擴展版本。

#include <sys/epoll.h>int epoll_create (int size)

調用成功后,epoll_create()創建一個epoll實例,返回與該實例關聯的文件描述符。這個文件描述符和真正的文件沒有關系,僅僅是為了后續調用使用epoll而創建的。size參數告訴內核需要監聽的文件描述符數目,但不是最大值。傳遞一個適當的近似值會帶來性能的提升,但不需要給出確切的數字。出錯時,返回-1,設置errno為下列值之一:

EINVAL   size不是正數

ENFILE    系統達到打開文件數的上限

ENOMEN    沒有足夠內存完成該次操作。

標準調用如下:

int epfd;epfd = epoll_create (100); if (epfd <0 )perror("epoll_create");

epoll_create返回的文件描述符需要用close()關閉。

2、控制 epoll

epoll_ctl 可以向指定的epoll上下文加入或刪除文件描述符:

#include <sys/epoll.h>int epoll_ctl (int epfd, int op, int fd, struct epoll_event *event);
頭文件<sys/epoll.h>中定義了epoll event結構體
struct epoll_event {_u32 events;union {void * ptr;int fd;_u32 u32;_u64 u64;}data;};
epoll_ctl()成功調用將關聯epoll實例和epfd。參數op指定對fd要進行的操作。event參數描述epoll更具體的行為
以下是參數op的有效值:
EPOLL_CTL_ADD 把fd指定的文件添加到epfd指定的epoll實例監聽集中,監聽event中定義的事件。
EPOLL_CTL_DEL 把fd指定的文件從epfd指定的epoll監聽集中刪除。
EPOLL_CTL_MOD 使用event改變在已有fd上的監聽行為。
epoll_event結構體中的event參數列出了在給定文件描述符上監聽的事件。多個事件可以使用位或運算同時指定。以下是有效值:
EPOLLERR 文件出錯。即使不設置這個標志,這個事件也是被監聽的。
EPOLLET 使用邊沿觸發。默認是水平觸發。
EPOLLHUP 文件被掛起。即使不設置這個標志,這個事件也是被監聽的。
EPOLLIN 文件未阻塞,可讀。
EPOLLONESHOT 在一次事件產生被處理之后,文件不在被監聽。必須不再被監聽。必須使用EPOLL_CTL_MOD指定新的事件,以便重新監聽文件。
EPOLLOUT 文件未阻塞,可寫。
EPOLLPRI 高優先級的帶外數據可讀。
event_poll中的data字段由用戶使用。確認監聽事件后,data會被返回給用戶。通常將event.data.fd設定為fd,這樣就可以知道那個文件描述符觸發事件。
成功后,epoll_ctl()返回0.失敗返回-1,并設置errno為下列值:
EBADF epfd不是一個有效的epoll實例,或者fd不是有效文件描述符。
EEXIST op為EPOLL_CTL_ADD,但是fd已經與epfd關聯。
EINVAL epfd不是一個epoll實例,epfd和fd相同,或者op無效。
ENOENT op是EPOLL_CTL_MOD或者是EPOLL_CTL_DEL,但是fd沒有與epfd關聯。
ENOMEN 沒有足夠內存完成進程的請求。
EPERM fd不支持epoll。
在epfd實例中加入一個fd指定的監聽文件,使用如下代碼:
struct epoll_event event;int ret;event.data.fd = fd;/*return the fd to us later*/event.events = EPOLLIN|EPOLLOUT  ;ret = epoll_ctl (epfd,EPOLL_CTL_MOD,fd,&event);if (ret)perror ("epoll_ctl");
修改epfd實例中的fd上的一個監聽事件,可以使用如下代碼:
struct epoll_event event;int ret;event.data.fd = fd;/*return the fd to us later*/event.events = EPOLLIN ;ret = epoll_ctl (epfd,EPOLL_CTL_MOD,fd,&event);if (ret)perror ("epoll_ctl");
刪除一個fd監聽事件,可以使用如下代碼:
struct epoll_event event;int ret;event.data.fd = fd;/*return the fd to us later*/event.events = EPOLLIN ;ret = epoll_ctl (epfd,EPOLL_CTL_DEL,fd,&event);if (ret)perror ("epoll_ctl");
3、等待Epoll事件
epoll_wait()等待給定epoll實例關聯的文件描述符上的事件:
#include <sys/epoll.h>int epoll_wait (int epfd, struct epoll_event * * events, int maxevents, int timeout);
對epoll_wait()的調用等待epoll實例epfd中的文件fd上的事件,時限為timeout毫秒。成功返回,struct epoll_event *events指向包含epoll_event結構體(該結構體描述了每個事件)的內存,且最多可以有maxevents
個事件。這樣可以根據events結構體來確定哪些fd觸發了事件,從而做出相應的處理。返回值是事件數,出錯返回-1,并將errno設置為以下值
EBADF epfd是無效文件描述符
EFAULT 進程對events指向的內存無寫權限
EINTR 系統調用在完成前被信號中斷
EINVAL epfd不是有效的epoll實例,或者maxevents小于等于0
如果timeout 為0.即使沒有事件發生,調用也立即發生,此時調用返回0.如果timeout為-1,調用將一直等待到有事件發生。
當調用epoll_wait()返回,epoll_event結構體中的events數組描述了一次等待發生的事件,最多返回maxevents個事件。data字段包含了用戶在調用epoll_ctl前的設置,
如文件的句柄,用來區分那個文件所發生的事件。
一個完整的epoll_wait()例子如下:
#define MAX_EVENTS   64struct epoll_event * events = NULL;int nr_events, i, epfd;events = malloc (sizeof(struct epoll_event) * MAX_EVENTS);if (! events ){perror("malloc");exit(-1);}nr_events = epoll_wait (epfd,events,MAX_EVENTS,-1);if (nr_events < 0){perror("epoll_wait");free(events);exit (-1);}for (int i=0; i<nr_eventsl i++)printf("event = %d on fd = %d /n",events[i].events,events[i].data.fd); 
4、邊沿觸發時間和水平觸發事件

EPOLL事件有兩種模型 Level Triggered (LT)Edge Triggered (ET):

LT(level triggered,水平觸發模式)是缺省的工作方式,并且同時支持 block 和 non-block socket。在這種做法中,內核告訴你一個文件描述符是否就緒了,然后你可以對這個就緒的fd進行IO操作。如果你不作任何操作,內核還是會繼續通知你的,所以,這種模式編程出錯誤可能性要小一點。

ET(edge-triggered,邊緣觸發模式)是高速工作方式,只支持no-block socket。在這種模式下,當描述符從未就緒變為就緒時,內核通過epoll告訴你。然后它會假設你知道文件描述符已經就緒,并且不會再為那個文件描述符發送更多的就緒通知,等到下次有新的數據進來的時候才會再次出發就緒事件。

5、man epoll 中的實例

setnonblocking()函數將socket文件設置為非阻塞,因為使用的是ET模式。do_use_fd()是對此文件做出一定的處理,如讀寫等。

#define MAX_EVENTS 10struct epoll_event ev, events[MAX_EVENTS];int listen_sock, conn_sock, nfds, epollfd;/* Set up listening socket, 'listen_sock' (socket(),    bind(), listen()) */epollfd = epoll_create(10);if (epollfd == -1) {    perror("epoll_create");    exit(EXIT_FAILURE);}ev.events = EPOLLIN;ev.data.fd = listen_sock;if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {    perror("epoll_ctl: listen_sock");    exit(EXIT_FAILURE);}for (;;) {    nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);    if (nfds == -1) {        perror("epoll_pwait");        exit(EXIT_FAILURE);    }    for (n = 0; n < nfds; ++n) {        if (events[n].data.fd == listen_sock) {            conn_sock = accept(listen_sock,                            (struct sockaddr *) &local, &addrlen);            if (conn_sock == -1) {                perror("accept");                exit(EXIT_FAILURE);            }            setnonblocking(conn_sock);            ev.events = EPOLLIN | EPOLLET;            ev.data.fd = conn_sock;            if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,                        &ev) == -1) {                perror("epoll_ctl: conn_sock");                exit(EXIT_FAILURE);            }        } else {            do_use_fd(events[n].data.fd);        }    }}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
综合国产在线视频| 最近2019中文免费高清视频观看www99| 欧洲成人免费视频| 精品一区二区三区电影| 国产在线98福利播放视频| 欧美巨猛xxxx猛交黑人97人| 亚洲免费电影一区| 国产主播精品在线| 欧美日韩一区二区三区在线免费观看| 国外成人在线直播| 欧美精品第一页在线播放| 日韩网站免费观看高清| 国产精品久久久久久久久久久久久| 亚洲精品视频播放| 日韩在线播放av| 久久精品这里热有精品| 亚洲日本成人女熟在线观看| 久久久成人精品视频| 成人黄色在线观看| 最新亚洲国产精品| 日韩暖暖在线视频| 萌白酱国产一区二区| 欧美在线一级va免费观看| 最新的欧美黄色| 欧美成人三级视频网站| 色综合久久天天综线观看| 久久精品成人欧美大片古装| 亚洲无av在线中文字幕| 欧美最顶级丰满的aⅴ艳星| 亚洲一区二区三区视频播放| 国产日韩综合一区二区性色av| 欧美中文字幕视频在线观看| 国产亚洲福利一区| 亚洲第五色综合网| 国产91精品高潮白浆喷水| 欧美老少做受xxxx高潮| 91av在线播放| 久久精品国产一区| 亚洲男人天堂视频| 中文字幕精品久久| www国产亚洲精品久久网站| 成人a视频在线观看| 国产精品欧美久久久| 欧美夫妻性生活xx| 日韩在线免费高清视频| 亚洲日韩欧美视频| 亚洲精品不卡在线| 亚洲国产精品va在线| 亚洲欧美日韩视频一区| 欧美激情小视频| 国产精品69精品一区二区三区| 日韩一二三在线视频播| 久久这里只有精品视频首页| 久久综合久久88| 91av网站在线播放| 91香蕉嫩草影院入口| 国产精品永久免费视频| 在线a欧美视频| 日韩在线观看免费网站| 欧美成人国产va精品日本一级| 亚洲精品电影在线观看| 欧美精品在线观看| 色妞色视频一区二区三区四区| 中国日韩欧美久久久久久久久| 欧美视频中文字幕在线| 高跟丝袜一区二区三区| 亚洲免费视频一区二区| 久久久精品2019中文字幕神马| 日韩欧美国产视频| 91精品国产91久久久久| 国产suv精品一区二区三区88区| 精品成人在线视频| 在线看片第一页欧美| 狠狠色狠狠色综合日日五| 精品视频在线观看日韩| 中文字幕亚洲激情| 日韩av在线网| 成人日韩在线电影| 欧美成年人视频网站欧美| 久久人人爽亚洲精品天堂| 2019精品视频| 韩国视频理论视频久久| 国产精品免费在线免费| 午夜精品一区二区三区在线| 亚洲成年人在线播放| 7m精品福利视频导航| 色综合久久久久久中文网| 日韩免费高清在线观看| 日本久久久久久| 国产精品久久久久久久久久99| 欧美日韩在线视频首页| 久久不射电影网| 国产成人免费av电影| 91福利视频在线观看| 久久精品成人欧美大片古装| 久久五月情影视| 久久久免费精品| 亚洲国产精品yw在线观看| 日本国产精品视频| 国产情人节一区| 亚洲日本欧美中文幕| 欧美精品videossex性护士| 欧美精品日韩www.p站| 视频在线一区二区| 欧美视频二区36p| 亚洲a在线观看| 成人网欧美在线视频| 亚洲欧美变态国产另类| 欧洲成人在线视频| 青青草精品毛片| 在线播放日韩欧美| 亚洲精品电影在线观看| 色狠狠久久aa北条麻妃| 欧美性做爰毛片| 国产日产欧美精品| 日韩激情第一页| 九九久久精品一区| 亚洲国语精品自产拍在线观看| 欧亚精品中文字幕| 国产精品日韩在线观看| 中日韩美女免费视频网站在线观看| 国产91精品高潮白浆喷水| 日本精品视频在线观看| 欧美精品久久久久a| 亚洲国产天堂久久国产91| 久久精品国产亚洲精品| 国产精品丝袜久久久久久高清| 亚洲国产成人精品一区二区| 91免费国产网站| 日韩福利视频在线观看| 亚洲欧美国产精品久久久久久久| 国产精品成人v| 国产亚洲精品久久久| 欧美成人黑人xx视频免费观看| 国产精品美女久久久久久免费| 91久久久久久久一区二区| 精品动漫一区二区| 亚洲人午夜精品免费| 亚洲毛片一区二区| 人体精品一二三区| 欧美午夜电影在线| 成人午夜在线影院| 在线观看91久久久久久| 国产精品视频久久久久| 久久人人爽人人爽爽久久| 欧美日韩免费区域视频在线观看| 久久免费国产精品1| 97精品视频在线播放| 中文字幕精品一区久久久久| 欧美韩国理论所午夜片917电影| 欧美高清在线视频观看不卡| 成人网址在线观看| 日韩欧美中文字幕在线观看| 成人黄色免费网站在线观看| 毛片精品免费在线观看| 国语自产偷拍精品视频偷| 欧美视频13p| 欧洲成人性视频| 久久人人爽人人爽爽久久| 亚洲区一区二区| 欧美猛交ⅹxxx乱大交视频| 久久精品国产2020观看福利| 亚洲欧美国产精品久久久久久久| 91精品久久久久久久久久另类|