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

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

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

關(guān)于Eventloop的概念

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

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

1、Eventloop 是什么?

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

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

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

舉個(gè)簡(jiǎn)單的例子:

intmain()
{
intchoice;

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

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

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

exit(EXIT_SUCCESS);

}

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

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

Eventloop 隨處可見:

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

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

多媒體庫 SDL2 里的 SDL_PollEvent();

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

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

合格的 Eventloop:

一個(gè)合格的 Eventloop,需要有哪些特性?

我個(gè)人認(rèn)為:

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

2、能異步處理事件。

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

滿足上述三點(diǎn),這個(gè) Eventloop 在功能上就是夠用的。

2、Eventloop 怎么用?

基于 select 的 Eventloop:

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

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
}
}

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

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

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

各種開源的 Eventloop 庫:

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

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

libevent:an event notification library.

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

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

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

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

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

點(diǎn)擊查看大圖

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

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

#include
#include

//定義兩個(gè)事件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);

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

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

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

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

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

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

審核編輯:湯梓紅

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

    關(guān)注

    3

    文章

    3368

    瀏覽量

    42564
  • javascript
    +關(guān)注

    關(guān)注

    0

    文章

    519

    瀏覽量

    53888

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

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

收藏 人收藏

    評(píng)論

    相關(guān)推薦

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    視頻簡(jiǎn)介:視頻主講關(guān)于電池的基礎(chǔ)關(guān)于電池的元素和概念。主要介紹了燃油測(cè)量技術(shù),闡述了關(guān)機(jī)電壓、放電率、溫度和電池年齡的內(nèi)在關(guān)系。
    的頭像 發(fā)表于 03-27 06:01 ?4253次閱讀
    <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 ?7285次閱讀