日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
深入淺出:Linux中epoll庫之使用方法(linuxepoll庫)

Linux中有很多I/O多路復(fù)用的機(jī)制,其中epoll是比較常用的一種。epoll可以用來監(jiān)聽一個文件描述符,當(dāng)其中任意一個文件描述符有數(shù)據(jù)可讀或可寫時,會通過回調(diào)函數(shù)通知應(yīng)用程序進(jìn)行相應(yīng)的處理。在高并發(fā)的網(wǎng)絡(luò)編程中,使用epoll可以大幅度提高程序的并發(fā)性和響應(yīng)速度。本文將介紹使用epoll進(jìn)行網(wǎng)絡(luò)編程的相關(guān)知識和使用方法。

創(chuàng)新互聯(lián)專注于??h企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè),購物商城網(wǎng)站建設(shè)???h網(wǎng)站建設(shè)公司,為??h等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站開發(fā),專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

一、epoll的工作原理

epoll的工作原理相對于其他I/O多路復(fù)用機(jī)制而言比較復(fù)雜。當(dāng)我們調(diào)用epoll_create函數(shù)時,會返回一個文件描述符epfd。我們可以通過epoll_ctl函數(shù)來向epfd中添加或刪除文件描述符,或者對其進(jìn)行一些控制操作。當(dāng)我們需要對epfd的所有文件描述符進(jìn)行監(jiān)聽時,可以調(diào)用epoll_wt函數(shù),該函數(shù)會一直阻塞直到有文件描述符有數(shù)據(jù)可讀或可寫。

二、epoll的優(yōu)點(diǎn)

epoll的優(yōu)點(diǎn)主要體現(xiàn)在以下幾個方面:

1. 支持大量的并發(fā)連接,可以監(jiān)聽上萬個文件描述符。

2. 支持高效的事件通知機(jī)制,當(dāng)有文件描述符有數(shù)據(jù)可讀或可寫時,會立即通知應(yīng)用程序。

3. 支持邊緣觸發(fā)和水平觸發(fā)兩種模式,可以根據(jù)實(shí)際需求進(jìn)行選擇。

4. 支持使用epoll_ctl函數(shù)對監(jiān)聽的文件描述符進(jìn)行添加、刪除和修改操作,非常靈活。

三、epoll的使用方法

1. 創(chuàng)建epoll對象

我們可以通過epoll_create函數(shù)來創(chuàng)建epoll對象,該函數(shù)會返回一個文件描述符epfd,該描述符用來操作epoll對象。

“`

#include

int epoll_create(int size);

“`

參數(shù)size指定epoll對象中能夠監(jiān)聽的文件描述符數(shù)量,該參數(shù)在Linux 2.6.8以后已經(jīng)不再使用。如果該參數(shù)被設(shè)置為0,則epoll_create函數(shù)會自動根據(jù)系統(tǒng)的默認(rèn)值創(chuàng)建epoll對象。

2. 向epoll對象中添加文件描述符

我們可以通過epoll_ctl函數(shù)向epoll對象中添加或刪除文件描述符,或者修改其監(jiān)聽事件的屬性。

“`

#include

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

“`

參數(shù)epfd指定了需要操作的epoll對象的文件描述符,參數(shù)op指定了操作類型,參數(shù)fd表示需要監(jiān)聽的文件描述符,參數(shù)event則描述了需要監(jiān)聽的事件類型。

下面是event結(jié)構(gòu)體的定義:

“`

struct epoll_event {

uint32_t events; /* 監(jiān)聽的事件類型,可以是EPOLLIN、EPOLLOUT、EPOLLRDHUP等 */

epoll_data_t data; /* 回調(diào)函數(shù)參數(shù) */

};

“`

我們可以通過events參數(shù)指定需要監(jiān)聽的事件類型,比如數(shù)據(jù)可讀、數(shù)據(jù)可寫、關(guān)閉連接等。在使用epoll的過程中,常常要用到以下幾種事件類型:

“`

EPOLLIN:表示文件可讀。

EPOLLOUT:表示文件可寫。

EPOLLERR:表示文件出現(xiàn)錯誤。

EPOLLRDHUP:表示文件的連接被斷開。

EPOLLHUP:表示連接被掛起。

“`

3. 進(jìn)行epoll_wt監(jiān)聽

我們可以通過epoll_wt函數(shù)監(jiān)聽epoll對象中的文件描述符,當(dāng)有文件描述符有數(shù)據(jù)可讀或可寫時,會立即通知應(yīng)用程序。

“`

#include

int epoll_wt(int epfd, struct epoll_event *events, int maxevents, int timeout);

“`

參數(shù)epfd指定了需要監(jiān)聽的epoll對象的文件描述符,參數(shù)events用來存儲已經(jīng)發(fā)生事件的文件描述符和事件類型,參數(shù)maxevents表示更大需要監(jiān)聽的事件數(shù)量,參數(shù)timeout表示epoll_wt函數(shù)的超時時間。

epoll_wt函數(shù)會阻塞直到有文件描述符有數(shù)據(jù)可讀或可寫。當(dāng)epoll_wt函數(shù)返回時,events參數(shù)中存儲的就是已經(jīng)發(fā)生的事件。

4. 處理epoll_wt返回的事件

在使用epoll進(jìn)行網(wǎng)絡(luò)編程時,常常需要在epoll_wt返回后對事件進(jìn)行處理。通常的做法是遍歷事件列表,針對每個事件單獨(dú)進(jìn)行處理。

下面是一個示例代碼:

“`

struct epoll_event events[1024];

int nfds = epoll_wt(epfd, events, 1024, -1);

for (int i = 0; i

int sockfd = events[i].data.fd;

if (events[i].events & EPOLLIN) { // 可讀事件

// 處理數(shù)據(jù)讀取邏輯

} else if (events[i].events & EPOLLOUT) { // 可寫事件

// 處理數(shù)據(jù)發(fā)送邏輯

} else {

// 處理其他事件,比如連接關(guān)閉、連接錯誤等

}

}

“`

在實(shí)際使用中,我們還需要關(guān)閉文件描述符、重新注冊事件等一些操作。但以上代碼已經(jīng)涵蓋了epoll的基本使用方法。

四、

相關(guān)問題拓展閱讀:

  • Linux中select poll和epoll的區(qū)別
  • 淺談Android之Linux pipe/epoll

Linux中select poll和epoll的區(qū)別

select/poll中,進(jìn)程只有在調(diào)用一定的方法后,內(nèi)核才對所有監(jiān)視的文件描述符進(jìn)行掃描,而epoll事先通過epoll_ctl()來注冊一

個文件描述符,一旦基于某個文件描述符就緒時,內(nèi)核會采用類似callback的回調(diào)機(jī)制伍歷寬爛桐,迅速激活這腔亮個文件描述符,當(dāng)進(jìn)程調(diào)用epoll_wait()

時便得到通知。

淺談Android之Linux pipe/epoll

管道

管道的概念:

管道是一種最基本的IPC機(jī)制,作用于有血緣關(guān)系的進(jìn)程之間臘仔掘,完成數(shù)據(jù)傳遞。調(diào)用pipe系統(tǒng)函數(shù)即可創(chuàng)建一個管道。有如下特質(zhì):

1. 其本質(zhì)是一個偽文件(實(shí)為內(nèi)核緩沖區(qū))

2. 由兩個文件描述符引用,一個表示讀端,一個表示寫端。

3. 規(guī)定數(shù)據(jù)從管道的寫端流入管道,從讀端流出。

管道的原理: 管道實(shí)為內(nèi)核使用環(huán)形隊列機(jī)制,借助內(nèi)核緩沖區(qū)(4k)實(shí)現(xiàn)。

管道的局限性:

① 數(shù)據(jù)自己讀不能自己寫。

② 數(shù)據(jù)一旦被讀走,便不在管道中存在,不可反復(fù)讀取。

③ 由于管道采用半雙工通信方式。因此,數(shù)據(jù)只能在一個方向上流動。

④ 只能在有公共祖先的進(jìn)程間使用管道。

常見的通信方式有,單工通信、半雙工通信、全雙工通信。

簡單來說這個管道是一個文件,但又和普通輪核文件不通:管道緩沖區(qū)大小一般為1頁,即4K字節(jié),管道分讀端和寫端,讀端負(fù)責(zé)從管道拿數(shù)據(jù),當(dāng)數(shù)據(jù)為空時則阻塞;寫端向管道寫數(shù)據(jù),當(dāng)管道緩存區(qū)滿時則阻塞。

pipe函數(shù)

創(chuàng)建管道

    int pipe(int pipefd); 成功:0;失?。?1,設(shè)置errno

函數(shù)調(diào)用成功返回r/w兩個文件描述符。無需open,但需手動close。規(guī)定:fd → r; fd → w,就像0對應(yīng)標(biāo)準(zhǔn)輸入,1對應(yīng)標(biāo)準(zhǔn)輸出一樣。向管道文件讀寫數(shù)據(jù)其實(shí)是在讀寫內(nèi)核緩沖區(qū)。

管道創(chuàng)建成功以后,創(chuàng)建該管道的進(jìn)程(父進(jìn)程)同時掌握著管道的讀端和寫端。如何實(shí)現(xiàn)父子進(jìn)程間通信呢?通??梢圆捎萌缦虏襟E:

1. 父進(jìn)程調(diào)用pipe函數(shù)創(chuàng)建管道,得到兩個文件描述符fd、fd指向管道的讀端和寫端。

2. 父進(jìn)程調(diào)用fork創(chuàng)建子進(jìn)程,那么子進(jìn)程也有兩個文件描述符指向同一管道。

3. 父進(jìn)程關(guān)閉管道讀端,子進(jìn)程關(guān)閉管道寫端。父進(jìn)程可以向管道中寫入數(shù)據(jù),子進(jìn)程將管道中的數(shù)據(jù)讀出。由于管道戚芹是利用環(huán)形隊列實(shí)現(xiàn)的,數(shù)據(jù)從寫端流入管道,從讀端流出,這樣就實(shí)現(xiàn)了進(jìn)程間通信。

管道的讀寫行為

    使用管道需要注意以下4種特殊情況(假設(shè)都是阻塞I/O操作,沒有設(shè)置O_NONBLOCK標(biāo)志):

1. 如果所有指向管道寫端的文件描述符都關(guān)閉了(管道寫端引用計數(shù)為0),而仍然有進(jìn)程從管道的讀端讀數(shù)據(jù),那么管道中剩余的數(shù)據(jù)都被讀取后,再次read會返回0,就像讀到文件末尾一樣。

2. 如果有指向管道寫端的文件描述符沒關(guān)閉(管道寫端引用計數(shù)大于0),而持有管道寫端的進(jìn)程也沒有向管道中寫數(shù)據(jù),這時有進(jìn)程從管道讀端讀數(shù)據(jù),那么管道中剩余的數(shù)據(jù)都被讀取后,再次read會阻塞,直到管道中有數(shù)據(jù)可讀了才讀取數(shù)據(jù)并返回。

3. 如果所有指向管道讀端的文件描述符都關(guān)閉了(管道讀端引用計數(shù)為0),這時有進(jìn)程向管道的寫端write,那么該進(jìn)程會收到信號SIGPIPE,通常會導(dǎo)致進(jìn)程異常終止。當(dāng)然也可以對SIGPIPE信號實(shí)施捕捉,不終止進(jìn)程。具體方法信號章節(jié)詳細(xì)介紹。

4. 如果有指向管道讀端的文件描述符沒關(guān)閉(管道讀端引用計數(shù)大于0),而持有管道讀端的進(jìn)程也沒有從管道中讀數(shù)據(jù),這時有進(jìn)程向管道寫端寫數(shù)據(jù),那么在管道被寫滿時再次write會阻塞,直到管道中有空位置了才寫入數(shù)據(jù)并返回。

總結(jié):

① 讀管道: 1. 管道中有數(shù)據(jù),read返回實(shí)際讀到的字節(jié)數(shù)。

2. 管道中無數(shù)據(jù):

(1) 管道寫端被全部關(guān)閉,read返回0 (好像讀到文件結(jié)尾)

  (2) 寫端沒有全部被關(guān)閉,read阻塞等待(不久的將來可能有數(shù)據(jù)遞達(dá),此時會讓出cpu)

    ② 寫管道: 1. 管道讀端全部被關(guān)閉, 進(jìn)程異常終止(也可使用捕捉SIGPIPE信號,使進(jìn)程不終止)

2. 管道讀端沒有全部關(guān)閉:

(1) 管道已滿,write阻塞。

(2) 管道未滿,write將數(shù)據(jù)寫入,并返回實(shí)際寫入的字節(jié)數(shù)。

Epoll的概念

Epoll可以使用一次等待監(jiān)聽多個描述符的可讀/可寫狀態(tài).等待返回時攜帶了可讀的描述符或者自定義的數(shù)據(jù).不需要為每個描述符創(chuàng)建獨(dú)立的線程進(jìn)行阻塞讀取,

Linux系統(tǒng)中的epoll機(jī)制為處理大批量句柄而作了改進(jìn)的poll,是Linux下多路復(fù)用IO接口select/poll的增強(qiáng)版本,它能顯著減少程序在大量并發(fā)連接中只有少量活躍的情況下的系統(tǒng)CPU利用率

(01) pipe(wakeFds),該函數(shù)創(chuàng)建了兩個管道句柄。

(02) mWakeReadPipeFd=wakeFds,是讀管道的句柄。

(03) mWakeWritePipeFd=wakeFds 1 ,是寫管道的句柄。

(04) epoll_create(EPOLL_SIZE_HINT)是創(chuàng)建epoll句柄。

(05) epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem),它的作用是告訴mEpollFd,它要監(jiān)控mWakeReadPipeFd文件描述符的EPOLLIN事件,即當(dāng)管道中有內(nèi)容可讀時,就喚醒當(dāng)前正在等待管道中的內(nèi)容的線程。

回到Android中的epoll大致流程如下:?

Looper.loop -> MessageQueue.nativePollOnce

epoll_create()   epoll_ctl() 注冊事件的回調(diào)

looper.pollInner() -> epoll_wait() 等待接受事件喚醒的回調(diào)

 MessageQueue.enqueueMessage(Message msg, long when)    ->  MessageQueue.nativeWake(long ptr)

參考鏈接如下

鏈接:

鏈接:

linux epoll庫的介紹就聊到這里吧,感謝你花時間閱讀本站內(nèi)容,更多關(guān)于linux epoll庫,深入淺出:Linux中epoll庫之使用方法,Linux中select poll和epoll的區(qū)別,淺談Android之Linux pipe/epoll的信息別忘了在本站進(jìn)行查找喔。

成都創(chuàng)新互聯(lián)建站主營:成都網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、網(wǎng)站改版的網(wǎng)站建設(shè)公司,提供成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、成都網(wǎng)站推廣、成都網(wǎng)站優(yōu)化seo、響應(yīng)式移動網(wǎng)站開發(fā)制作等網(wǎng)站服務(wù)。


本文標(biāo)題:深入淺出:Linux中epoll庫之使用方法(linuxepoll庫)
當(dāng)前網(wǎng)址:http://m.5511xx.com/article/dhjsjso.html