【c++】26.浅谈“事件驱动”、select、poll、epoll
淺談“事件驅(qū)動(dòng)”
1.通常,我們?cè)O(shè)計(jì)一個(gè)事件處理模型的程序有兩種思路:
- 一種是通過(guò)輪詢的方式;
- 一種通過(guò)事件驅(qū)動(dòng)的方式,事件驅(qū)動(dòng)方式也被稱為消息通知方式。
下面舉個(gè)簡(jiǎn)單收信的例子,來(lái)說(shuō)明兩種實(shí)現(xiàn)方式的不同:
- (1) 傳統(tǒng)的郵件,郵遞員把它放到你家的郵箱里。因?yàn)槟悴恢朗裁磿r(shí)候有郵件,所以你要經(jīng)常去檢查郵箱,最近到底有沒(méi)有郵件。這就是所謂的輪詢方式,你要時(shí)常去檢查,有沒(méi)有發(fā)生事件發(fā)生,當(dāng)你檢查到有事件發(fā)生時(shí),你采取相應(yīng)措施,處理相關(guān)事件。
- (2)現(xiàn)代的電子郵件,你不用自己去查看郵箱,如果有新郵件,電腦會(huì)給你發(fā)消息,提示你有新郵件,然后你去查看郵箱。這就是所謂的事件驅(qū)動(dòng)(消息通知),你不用去關(guān)心事件什么時(shí)候發(fā)生,當(dāng)有事件發(fā)生時(shí),會(huì)有人通知你,事件發(fā)生了,然后你再采取相應(yīng)的措施,處理相關(guān)事件。
通過(guò)上面的例子,可以看出,輪詢的最大的弊端在于,你要做許多無(wú)謂的檢查,具體到程序中,就是會(huì)有CPU資源的浪費(fèi),換言之,就是CPU利用率不高。而事件驅(qū)動(dòng),就很好的解決了這個(gè)問(wèn)題。不過(guò)事件驅(qū)動(dòng)的缺點(diǎn)在于,模型較為復(fù)雜,程序?qū)懫饋?lái)會(huì)比較復(fù)雜,但是,一旦掌握了事件驅(qū)動(dòng)這種模型的基本設(shè)計(jì)思路,必定能達(dá)到事半功倍的效果。
2.網(wǎng)絡(luò)服務(wù)器設(shè)計(jì)過(guò)程中用到的 事件驅(qū)動(dòng)模型
在這里我要說(shuō)一說(shuō),通常的網(wǎng)絡(luò)服務(wù)器設(shè)計(jì)過(guò)程中的事件驅(qū)動(dòng)模型,希望能對(duì)需要幫助的朋友一點(diǎn)小小的幫助,這將是我很樂(lè)意看到的。
通常,高吞吐、大并發(fā)的網(wǎng)絡(luò)服務(wù)器,都會(huì)采用事件驅(qū)動(dòng)模型,其優(yōu)點(diǎn)就是CPU利用率高,寫(xiě)出來(lái)的程序效率比較高。
通常,我們會(huì)用select/poll/epoll,這些由系統(tǒng)提供的I/O復(fù)用的API來(lái)實(shí)現(xiàn)事件驅(qū)動(dòng)模型。
網(wǎng)絡(luò)程序中的事件,通常可以分為三類:
- 一類是可讀事件(數(shù)據(jù)已到達(dá)內(nèi)核,上層應(yīng)用可以調(diào)用相關(guān)讀接口進(jìn)行數(shù)據(jù)讀取);
- 一類是可寫(xiě)事件(內(nèi)核的寫(xiě)緩沖區(qū)有空余,上層應(yīng)用可以調(diào)用相關(guān)寫(xiě)接口進(jìn)行數(shù)據(jù)寫(xiě)入);
- 一類是異常(或出錯(cuò))事件(發(fā)生了異常情況,需要進(jìn)行異常處理)。
select和poll, 與epoll相比,當(dāng)并發(fā)數(shù)比較大的時(shí)候,性能差別會(huì)比較大,主要是因?yàn)閮?nèi)核通知事件的方式不同。
-
在select和poll中,內(nèi)核只是在通知有多少個(gè)fd上發(fā)生了事件,并在相應(yīng)的fd上做了標(biāo)記,上層應(yīng)用要想知道具體是那個(gè)fd上發(fā)生了什么事件,就必須去遍歷整個(gè)fd的集合。
-
而在epoll中,操作系統(tǒng)通知事件的方式是,把有事件發(fā)生的fd集合返回給上層應(yīng)用,這樣就不需要再去做無(wú)謂的遍歷了。尤其在并發(fā)數(shù)比較大(fd集合中fd個(gè)數(shù)多)的時(shí)候,它們之間的性能差別還是挺大的。因此,性能要求比較高的網(wǎng)絡(luò)服務(wù)器的實(shí)現(xiàn),大多都使用epoll。
下圖所示是一種比較常見(jiàn)的事件驅(qū)動(dòng)(消息通知)模型的簡(jiǎn)單實(shí)現(xiàn):
上圖中,EventMonitor是用來(lái)從操作系統(tǒng)獲取事件的線程,EventProcessor是實(shí)際來(lái)處理事件的線程。
在EventMonitor中調(diào)用select/poll/epoll_wait來(lái)獲取事件,然后把發(fā)生的事件,以消息的方式通知給EventProcessor,EventProcessor收到消息后,處理所發(fā)生的事件。
這里EventProcessor可以有多個(gè),同一個(gè)fd的上事件,一般在同一個(gè)EventProcessor上處理。這樣,EventMonitor的工作就是獲取事件,是比較輕量級(jí)的,重量級(jí)的運(yùn)算處理工作都由EventProcessor來(lái)處理,通過(guò)調(diào)整EventProcessor的個(gè)數(shù),提高CPU的利用效率,從而提高整個(gè)程序的性能。
總結(jié)
以上是生活随笔為你收集整理的【c++】26.浅谈“事件驱动”、select、poll、epoll的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【c++】24.std::functio
- 下一篇: 【c++】27.事件驱动、IO复用、se