0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

關(guān)于Eventloop的概念

Q4MP_gh_c472c21 ? 來源:老吳嵌入式 ? 作者:吳偉東Jack ? 2022-09-28 09:42 ? 次閱讀

最近了解了一下 Eventloop 這個概念,所以想寫一篇文章整理一下思路。

1、Eventloop 是什么?

我在網(wǎng)上看了一些資料,但都比較復(fù)雜,而且大多和 JavaScript 扯上關(guān)系,對初學(xué)者不友好。

我個人理解的 Eventloop,其實就是在一個大循環(huán)里,處理各種各樣的事件。只是不同的 Eventloop 機制或者庫,在性能和適用場景之間有差別罷了。

一個程序,只要它需要一直工作,就會處于一個持續(xù)循環(huán)運行的狀態(tài),我把這個循環(huán)的狀態(tài),稱為 Eventloop。

舉個簡單的例子:

intmain()
{
intchoice;

do{
//等待用戶輸入
choice=getch();

switch(choice){
case'q':
break;

case'a':
add_record();
break;
[...]
}
}while(choice!='q');

exit(EXIT_SUCCESS);

}

上面這個程序,在一個 while 循環(huán)里,根據(jù)不同的鍵盤輸入事件,而執(zhí)行不同的操作。

這就是一個簡單的 Eventloop,只是這個 Eventloop 只處理一種事件:鍵盤輸入,且是阻塞等待,雖然很簡陋,但是對于上面這個場景而言,已經(jīng)夠用了。

Eventloop 隨處可見:

許多開源軟件,只要它們有持續(xù)運行 + 事件處理的需求,就會有自己的 Eventloop 實現(xiàn),例如:

圖形庫 Qt 里的 QGuiApplication::run();

多媒體庫 SDL2 里的 SDL_PollEvent();

網(wǎng)絡(luò)庫 Mongoose 里的 mg_mgr_poll();

本質(zhì)上都是一種 Eventloop,只是由于需求和應(yīng)用場景的不一樣,各自的實現(xiàn)方法有所差異。

合格的 Eventloop:

一個合格的 Eventloop,需要有哪些特性?

我個人認(rèn)為:

1、不要阻塞,即不要調(diào)用可能會阻塞的系統(tǒng)調(diào)用,或總是以 nonblocking 的方式調(diào)用系統(tǒng)調(diào)用。

2、能異步處理事件。

3、性能盡量高,以滿足業(yè)務(wù)需求為下限。

滿足上述三點,這個 Eventloop 在功能上就是夠用的。

2、Eventloop 怎么用?

基于 select 的 Eventloop:

這是來自 UNIX 網(wǎng)絡(luò)編程 16.2 章節(jié)的一個例子,其大致代碼如下:

str_cli(FILE*fp,intsockfd)
{
...

//setnonblock
val=Fcntl(sockfd,F_GETFL,0);
Fcntl(sockfd,F_SETFL,val|O_NONBLOCK);

//eventloop
for(;;){
...
Select(maxfdp1,&rset,&wset,NULL,NULL);

if(FD_ISSET(sockfd,&rset)){
//dosomething
}

...//otherevent
}
}

這個程序會從標(biāo)準(zhǔn)輸入中讀取一行數(shù)據(jù),然后通過 socket 發(fā)送給服務(wù)端,然后接收服務(wù)端的響應(yīng),最后將響應(yīng)也寫到標(biāo)準(zhǔn)輸出。

最關(guān)鍵的點是先調(diào)用 fcntl 將所有的輸入輸出都設(shè)置為 nonblock,然后用 select 監(jiān)測所有的文件描述符。

基本上所有的開源事件庫,本質(zhì)上和這個程序沒差別。

各種開源的 Eventloop 庫:

由于 Eventloop 是一個比較通用的需求,在開源軟件里,有許多優(yōu)秀的異步事件庫都實現(xiàn)了這個功能。

比較適合嵌入式領(lǐng)域異步事件庫有 3 個:

libevent:an event notification library.

名氣最大,應(yīng)用最廣泛,歷史最悠久的跨平臺事件庫。

libev:a high performance full-featured event loop written in C.

較 libevent 而言,設(shè)計更簡練,但是對 Windows 支持不夠好,并且和開源社區(qū)不怎么接軌。

libuv:a multi-platform support library with a focus on asynchronous I/O.

6cbdc1f6-3e1d-11ed-9e49-dac502259ad0.jpg

點擊查看大圖

開發(fā) node.js 的過程中需要一個跨平臺的事件庫,目前非?;钴S,推薦大家重點學(xué)習(xí)。

libev 最精簡,入門最容易,這里用它來介紹一下事件庫的用法:

#include
#include

//定義兩個事件watcher
ev_iostdin_watcher;
ev_timertimeout_watcher;

//iowatcher的回調(diào)函數(shù)
staticvoid
stdin_cb(EV_P_ev_io*w,intrevents)
{
puts("stdinready");
ev_io_stop(EV_A_w);
ev_break(EV_A_EVBREAK_ALL);
}

//timerwatcher的回調(diào)函數(shù)
staticvoid
timeout_cb(EV_P_ev_timer*w,intrevents)
{
puts("timeout");
ev_break(EV_A_EVBREAK_ONE);
}

intmain(void)
{
//定義eventloop
structev_loop*loop=EV_DEFAULT;

//初始化iowatcher
ev_io_init(&stdin_watcher,stdin_cb,/*STDIN_FILENO*/0,EV_READ);
ev_io_start(loop,&stdin_watcher);

//初始化timerwatcher
ev_timer_init(&timeout_watcher,timeout_cb,2,0.);
ev_timer_start(loop,&timeout_watcher);

//啟動eventloop
ev_run(loop,0);
return0;
}

libev 用 watcher 來檢測各種事件,當(dāng)事件發(fā)生時,會調(diào)用 watcher 的回調(diào)函數(shù)。

那么,具體支持哪些事件類型呢?

6d124a14-3e1d-11ed-9e49-dac502259ad0.png

如果你對 libev 感興趣,可以根據(jù)下面這張圖閱讀其源碼:

6d573a34-3e1d-11ed-9e49-dac502259ad0.png6d8a6c2e-3e1d-11ed-9e49-dac502259ad0.png

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 開源
    +關(guān)注

    關(guān)注

    3

    文章

    3126

    瀏覽量

    42070
  • javascript
    +關(guān)注

    關(guān)注

    0

    文章

    515

    瀏覽量

    53658

原文標(biāo)題:不懂就問:什么是Eventloop?

文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    新手必看,關(guān)于ARM的22個常用概念

    文章具體介紹了關(guān)于ARM的22個常用概念。。##ARM體系結(jié)構(gòu)的存儲器格式
    發(fā)表于 08-28 18:57 ?6249次閱讀

    關(guān)于ARM的22個常用概念--的確經(jīng)典

    關(guān)于ARM的22個常用概念--的確經(jīng)典
    發(fā)表于 08-20 14:00

    關(guān)于數(shù)字電路的基本概念和學(xué)習(xí)內(nèi)容

    關(guān)于數(shù)字電路的基本概念和學(xué)習(xí)內(nèi)容初學(xué)硬件電子電路設(shè)計的你知道數(shù)字電路的基本概念嗎?知道數(shù)字電路都學(xué)什么內(nèi)容嗎?其實,電子電路硬件設(shè)計電路主要分為模電和數(shù)電兩部分,模電主要是關(guān)于電路分析
    發(fā)表于 07-22 16:46

    關(guān)于智能住宅若干概念

    關(guān)于智能住宅若干概念.doc
    發(fā)表于 09-10 13:35

    關(guān)于傳輸流以及傳輸流中幾個重要概念

    MPEG-2標(biāo)準(zhǔn)簡介以及數(shù)字電視功能分析關(guān)于傳輸流以及傳輸流中幾個重要概念信道解復(fù)用器是什么原理?
    發(fā)表于 04-21 06:53

    關(guān)于單片機的代碼和概念學(xué)習(xí)

    (需具有C語言基礎(chǔ))關(guān)于單片機的組件基礎(chǔ),請另行學(xué)習(xí),本文章只針對代碼和概念進行學(xué)習(xí),并不牽扯各個部件的連接步驟。首先看如下代碼:int val;//定義變量valint ledpin=13
    發(fā)表于 01-18 10:25

    關(guān)于虛擬HLR的概念,華為是否支持

    關(guān)于虛擬HLR的概念,華為是否支持 一個操作員可以對一定號段的用戶進行操作,互相之間不可見,不能干擾。這個一定的號段往往可以對
    發(fā)表于 06-30 09:47 ?670次閱讀

    關(guān)于計算機虛擬現(xiàn)實技術(shù)在概念設(shè)計中的實現(xiàn)

    關(guān)于計算機虛擬現(xiàn)實技術(shù)在概念設(shè)計中的實現(xiàn)  目前國際上流行的一種“故事版情景預(yù)言法”的概念設(shè)計,就是將要開發(fā)的產(chǎn)品置于一定的人、時、地、事和物中進行
    發(fā)表于 01-16 16:49 ?1076次閱讀

    關(guān)于單片機的一些基本概念

    關(guān)于單片機的一些基本概念  隨著電子技術(shù)的迅速發(fā)展,計算機已深入地滲透到我們的生活中,許多電子愛好者開始學(xué)習(xí)單片機知識,但單片機的內(nèi)容比較抽象,相
    發(fā)表于 03-18 16:54 ?1081次閱讀

    關(guān)于智能住宅若干概念

    關(guān)于智能住宅若干概念
    發(fā)表于 08-07 10:09 ?0次下載

    處理器關(guān)于多核概念與區(qū)別 多核處理器工作原理及優(yōu)缺點

    摘要:目前關(guān)于處理器的單核、雙核和多核已經(jīng)得到了普遍的運用,今天我們主要說說關(guān)于多核處理器的一些相關(guān)概念,它的工作與那里以及優(yōu)缺點而展開的分析。
    發(fā)表于 12-08 13:31 ?3.1w次閱讀

    關(guān)于噪聲的概念、產(chǎn)生及抑制方法的介紹

    4.6.1噪聲的基本概念
    的頭像 發(fā)表于 08-02 00:16 ?4638次閱讀

    關(guān)于鎖存器的time borrowing概念

    靜態(tài)時序分析經(jīng)常會遇到基于鎖存器(latch)的設(shè)計從而引入了一個概念稱為“Time Borrowing”。這篇文章向大家解釋了什么是time borrowing,以及鎖存器(latch)設(shè)計和時序
    發(fā)表于 10-02 07:54 ?913次閱讀

    關(guān)于電池的元素和概念介紹

    視頻簡介:視頻主講關(guān)于電池的基礎(chǔ)關(guān)于電池的元素和概念。主要介紹了燃油測量技術(shù),闡述了關(guān)機電壓、放電率、溫度和電池年齡的內(nèi)在關(guān)系。
    的頭像 發(fā)表于 03-27 06:01 ?4126次閱讀
    <b class='flag-5'>關(guān)于</b>電池的元素和<b class='flag-5'>概念</b>介紹

    ISO 26262中關(guān)于失效的概念

    嗨,大家好!今天打算給大家分享一下ISO 26262中關(guān)于失效的概念,這也是功能安全所圍繞的核心問題。
    的頭像 發(fā)表于 09-22 10:30 ?6889次閱讀