真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

自己動(dòng)手實(shí)現(xiàn)Epoll

自己動(dòng)手實(shí)現(xiàn)Epoll

成都創(chuàng)新互聯(lián)是一家專業(yè)提供浦東企業(yè)網(wǎng)站建設(shè),專注與做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、H5開發(fā)、小程序制作等業(yè)務(wù)。10年已為浦東眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。

Epoll是Linux IO多路復(fù)用的管理機(jī)制。作為現(xiàn)在Linux平臺(tái)高性能網(wǎng)絡(luò)IO必要的組件。內(nèi)核的實(shí)現(xiàn)可以參照:fs/eventpoll.c .

為什么需要自己實(shí)現(xiàn)epoll呢?現(xiàn)在自己打算做一個(gè)用戶態(tài)的協(xié)議棧。采用單線程的模式。https://github.com/wangbojing/NtyTcp,至于為什么要實(shí)現(xiàn)用戶態(tài)協(xié)議棧?可以自行百度C10M的問(wèn)題。

由于協(xié)議棧做到了用戶態(tài)故需要自己實(shí)現(xiàn)高性能網(wǎng)絡(luò)IO的管理。所以epoll就自己實(shí)現(xiàn)一下。代碼:https://github.com/wangbojing/NtyTcp/blob/master/src/nty_epoll_rb.c

?

在實(shí)現(xiàn)epoll之前,先得好好理解內(nèi)核epoll的運(yùn)行原理。內(nèi)核的epoll可以從四方面來(lái)理解。

1.?????Epoll的數(shù)據(jù)結(jié)構(gòu),rbtree對(duì)的存儲(chǔ),ready隊(duì)列存儲(chǔ)就緒io。

2.?????Epoll的線程安全,SMP的運(yùn)行,以及防止死鎖。

3.?????Epoll內(nèi)核回調(diào)。

4.?????Epoll的LT(水平觸發(fā))與ET(邊沿觸發(fā))

下面從這四個(gè)方面來(lái)實(shí)現(xiàn)epoll。

一、Epoll數(shù)據(jù)結(jié)構(gòu)

Epoll主要由兩個(gè)結(jié)構(gòu)體:eventpoll與epitem。Epitem是每一個(gè)IO所對(duì)應(yīng)的的事件。比如 epoll_ctl EPOLL_CTL_ADD操作的時(shí)候,就需要?jiǎng)?chuàng)建一個(gè)epitem。Eventpoll是每一個(gè)epoll所對(duì)應(yīng)的的。比如epoll_create 就是創(chuàng)建一個(gè)eventpoll。

Epitem的定義

自己動(dòng)手實(shí)現(xiàn)Epoll

Eventpoll的定義

自己動(dòng)手實(shí)現(xiàn)Epoll

數(shù)據(jù)結(jié)構(gòu)如下圖所示。

自己動(dòng)手實(shí)現(xiàn)Epoll

List 用來(lái)存儲(chǔ)準(zhǔn)備就緒的IO。對(duì)于數(shù)據(jù)結(jié)構(gòu)主要討論兩方面:insert與remove。同樣如此,對(duì)于list我們也討論insert與remove。何時(shí)將數(shù)據(jù)插入到list中呢?當(dāng)內(nèi)核IO準(zhǔn)備就緒的時(shí)候,則會(huì)執(zhí)行epoll_event_callback的回調(diào)函數(shù),將epitem添加到list中。

那何時(shí)刪除list中的數(shù)據(jù)呢?當(dāng)epoll_wait激活重新運(yùn)行的時(shí)候,將list的epitem逐一copy到events參數(shù)中。

Rbtree用來(lái)存儲(chǔ)所有io的數(shù)據(jù),方便快速通io_fd查找。也從insert與remove來(lái)討論。

對(duì)于rbtree何時(shí)添加:當(dāng)App執(zhí)行epoll_ctl EPOLL_CTL_ADD操作,將epitem添加到rbtree中。何時(shí)刪除呢?當(dāng)App執(zhí)行epoll_ctl EPOLL_CTL_DEL操作,將epitem添加到rbtree中。

List與rbtree的操作又如何做到線程安全,SMP,防止死鎖呢?

?

?

二、Epoll鎖機(jī)制

Epoll 從以下幾個(gè)方面是需要加鎖保護(hù)的。List的操作,rbtree的操作,epoll_wait的等待。

List使用最小粒度的鎖spinlock,便于在SMP下添加操作的時(shí)候,能夠快速操作list。

List添加

自己動(dòng)手實(shí)現(xiàn)Epoll

346行:獲取spinlock。

347行:epitem 的rdy置為1,代表epitem已經(jīng)在就緒隊(duì)列中,后續(xù)再觸發(fā)相同事件就只需更改event。

348行:添加到list中。

349行:將eventpoll的rdnum域 加1。

350行:釋放spinlock

?

List刪除

自己動(dòng)手實(shí)現(xiàn)Epoll

301行:獲取spinlock

304行:判讀rdnum與maxevents的大小,避免event溢出。

307行:循環(huán)遍歷list,判斷添加list不能為空

309行:獲取list首個(gè)結(jié)點(diǎn)

310行:移除list首個(gè)結(jié)點(diǎn)。

311行:將epitem的rdy域置為0,標(biāo)識(shí)epitem不再就緒隊(duì)列中。

313行:copy epitem的event到用戶空間的events。

316行:copy數(shù)量加1

317行:eventpoll中rdnum減一。

避免SMP體系下,多核競(jìng)爭(zhēng)。此處采用自旋鎖,不適合采用睡眠鎖。

?

Rbtree的添加

自己動(dòng)手實(shí)現(xiàn)Epoll

149行:獲取互斥鎖。

153行:查找sockid的epitem是否存在。存在則不能添加,不存在則可以添加。

160行:分配epitem。

167行:sockid賦值

168行:將設(shè)置的event添加到epitem的event域。

170行:將epitem添加到rbrtree中。

173行:釋放互斥鎖。

?

Rbtree刪除:

自己動(dòng)手實(shí)現(xiàn)Epoll

177行:獲取互斥鎖。

181行:刪除sockid的結(jié)點(diǎn),如果不存在,則rbtree返回-1。

188行:釋放epitem

190行:釋放互斥鎖。

?

Epoll_wait的掛起。

采用pthread_cond_wait,具體實(shí)現(xiàn)可以參照。

https://github.com/wangbojing/NtyTcp/blob/master/src/nty_epoll_rb.c

?

?

三、Epoll回調(diào)

Epoll 的回調(diào)函數(shù)何時(shí)執(zhí)行,此部分需要與Tcp的協(xié)議棧一起來(lái)闡述。Tcp協(xié)議棧的時(shí)序圖如下圖所示,epoll從協(xié)議?;卣{(diào)的部分從下圖的編號(hào)1,2,3,4。具體Tcp協(xié)議棧的實(shí)現(xiàn),后續(xù)從另外的文章中表述出來(lái)。下面分別對(duì)四個(gè)步驟詳細(xì)描述

編號(hào)1:是tcp三次握手,對(duì)端反饋ack后,socket進(jìn)入rcvd狀態(tài)。需要將監(jiān)聽socket的event置為EPOLLIN,此時(shí)標(biāo)識(shí)可以進(jìn)入到accept讀取socket數(shù)據(jù)。

編號(hào)2:在established狀態(tài),收到數(shù)據(jù)以后,需要將socket的event置為EPOLLIN狀態(tài)。

編號(hào)3:在established狀態(tài),收到fin時(shí),此時(shí)socket進(jìn)入到close_wait。需要socket的event置為EPOLLIN。讀取斷開信息。

編號(hào)4:檢測(cè)socket的send狀態(tài),如果對(duì)端cwnd>0是可以,發(fā)送的數(shù)據(jù)。故需要將socket置為EPOLLOUT。

所以在此四處添加EPOLL的回調(diào)函數(shù),即可使得epoll正常接收到io事件。

自己動(dòng)手實(shí)現(xiàn)Epoll

自己動(dòng)手實(shí)現(xiàn)Epoll自己動(dòng)手實(shí)現(xiàn)Epoll自己動(dòng)手實(shí)現(xiàn)Epoll

四、LT與ET

LT(水平觸發(fā))與ET(邊沿觸發(fā))是電子信號(hào)里面的概念。不清楚可以man epoll查看的。如下圖所示:

自己動(dòng)手實(shí)現(xiàn)Epoll

比如:event = EPOLLIN | EPOLLLT,將event設(shè)置為EPOLLIN與水平觸發(fā)。只要event為EPOLLIN時(shí)就能不斷調(diào)用epoll回調(diào)函數(shù)。

比如: event = EPOLLIN | EPOLLET,event如果從EPOLLOUT變化為EPOLLIN的時(shí)候,就會(huì)觸發(fā)。在此情形下,變化只發(fā)生一次,故只調(diào)用一次epoll回調(diào)函數(shù)。關(guān)于水平觸發(fā)與邊沿觸發(fā)放在epoll回調(diào)函數(shù)執(zhí)行的時(shí)候,如果為EPOLLET(邊沿觸發(fā)),與之前的event對(duì)比,如果發(fā)生改變則調(diào)用epoll回調(diào)函數(shù),如果為EPOLLLT(水平觸發(fā)),則查看event是否為EPOLLIN,即可調(diào)用epoll回調(diào)函數(shù)。

BAT, 滴滴,今日頭條,美圖,美團(tuán)等一線內(nèi)推 技術(shù)崗位內(nèi)推?

QQ群:935760465


當(dāng)前標(biāo)題:自己動(dòng)手實(shí)現(xiàn)Epoll
分享鏈接:http://weahome.cn/article/pccsci.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部