必修: PT協(xié)程--披著阻塞外皮的非阻塞任務(wù)

首先颁虐,協(xié)程的英文名是coroutine芒澜,是一種非搶占的任務(wù)形式仰剿。協(xié)程有很多種實(shí)現(xiàn)方式,Contiki里引入的PT協(xié)程痴晦,C語(yǔ)言標(biāo)準(zhǔn)庫(kù)里的setjmp.h等等南吮,都可以實(shí)現(xiàn)協(xié)程。協(xié)程運(yùn)行的時(shí)候誊酌,是以禪讓的方式退出的部凑,也就是說(shuō)我運(yùn)行夠了才會(huì)退出讓別人運(yùn)行。PT協(xié)程的幾種實(shí)現(xiàn)方式這里就不一一說(shuō)明了术辐,在網(wǎng)上可以找到不少資料砚尽。這里只是說(shuō)一下VSF中的事件驅(qū)動(dòng)的PT協(xié)程。

vsf_err_t example_thread(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
    vsfsm_pt_begin(pt);
    while (1)
    {
        ......
        vsfsm_pt_entry(pt);
        ......
        vsfsm_pt_entry(pt);
        ......
    }
    vsfsm_pt_end(pt);
}

VSF中的PT協(xié)程核心只是vsfsm_pt_begin辉词、vsfsm_pt_end和vsfsm_pt_entry敷搪。vsfsm_pt_begin在程序入口幢哨,功能為根據(jù)PT的狀態(tài),跳轉(zhuǎn)到對(duì)應(yīng)的entry繼續(xù)執(zhí)行闸与,如果狀態(tài)為0厂画,就不跳轉(zhuǎn)繼續(xù)往下執(zhí)行。vsfsm_pt_end是邏輯結(jié)構(gòu)上用的忽洛,表示PT協(xié)程代碼結(jié)束。vsfsm_pt_entry就是把當(dāng)前的執(zhí)行位置苍在,記錄到PT的狀態(tài)里,使得下一次調(diào)用的時(shí)候初肉,可以從記錄的位置開(kāi)始執(zhí)行。

上面的PT原理妄壶,其實(shí)都是通用的,不過(guò)VSF中的PT是設(shè)計(jì)為事件驅(qū)動(dòng)的PT,也就是說(shuō)屑埋,PT實(shí)際上续崖,底層也只是一個(gè)evt_handler(事件處理函數(shù))。

static struct vsfsm_state_t *
vsfsm_pt_evt_handler(struct vsfsm_t *sm, vsfsm_evt_t evt)
{
    struct vsfsm_pt_t *pt = (struct vsfsm_pt_t *)sm->user_data;

    switch (evt)
    {
    case VSFSM_EVT_ENTER:
    case VSFSM_EVT_EXIT:
        break;
    case VSFSM_EVT_INIT:
        pt->state = 0;
        // fall through
    default:
        pt->thread(pt, evt);
    }
    return NULL;
}

上面是VSF中的通用的PT底層的事件驅(qū)動(dòng)接口梢莽,只是在初始化事件中,初始化了PT的狀態(tài)變量轻局,然后除了ENTER和EXIT事件外置鼻,其他事件都直接調(diào)用PT線程來(lái)處理。從PT的初始化代碼中钙勃,也可以看出VSF中的PT是基于事件驅(qū)動(dòng)狀態(tài)機(jī)的:

vsf_err_t vsfsm_pt_init(struct vsfsm_t *sm, struct vsfsm_pt_t *pt)
{
    sm->user_data = pt;
    sm->init_state.evt_handler = vsfsm_pt_evt_handler;
    pt->sm = sm;
    return vsfsm_init(sm);
}

實(shí)際應(yīng)用代碼中同木,一般不會(huì)直接調(diào)用vsfsm_pt_entry,而且調(diào)用其他的輔助宏或者函數(shù):vsfsm_pt_wait远豺、vsfsm_pt_wfe(wait for event)、vsfsm_pt_wfpt(wait for pt)丽涩。分別代表等待下一個(gè)事件棺滞、等待直到收到指定事件、等待一個(gè)PT任務(wù)調(diào)用完成。這里只列舉一個(gè)vsfsm_pt_wfe的定義:

#define vsfsm_pt_wfe(pt, e)         \
    do {\
        evt = VSFSM_EVT_INVALID;\
        vsfsm_pt_entry(pt);\
        if (evt != (e)) return VSFERR_NOT_READY;\
    } while (0)

VSF中的PT協(xié)程返回VSFERR_NOT_READY表示還沒(méi)執(zhí)行完矮男;返回VSFERR_NONE表示已經(jīng)執(zhí)行完崔泵;如果返回小于0的指,則表示執(zhí)行出錯(cuò)。

按照PT協(xié)程的特性塞弊,一般適合用于“阻塞”代碼漱逸,實(shí)現(xiàn)后,運(yùn)行的方式確是非阻塞的游沿。當(dāng)然袋坑,也會(huì)有一些注意點(diǎn),比如

  1. 如果PT使用switch的方式事件的話眯勾,PT協(xié)程中的switch塊不能包含vsfsm_pt_entry枣宫。
  2. 由于PT協(xié)程是非阻塞婆誓,并不是一次調(diào)用就執(zhí)行完畢的,會(huì)分成多次調(diào)用也颤,所以洋幻,PT協(xié)程里的非靜態(tài)變量在一下次調(diào)用的時(shí)候,數(shù)值不同翅娶。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末文留,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子竭沫,更是在濱河造成了極大的恐慌厂庇,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件输吏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡替蛉,警方通過(guò)查閱死者的電腦和手機(jī)贯溅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)躲查,“玉大人它浅,你說(shuō)我怎么就攤上這事×椭螅” “怎么了姐霍?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)典唇。 經(jīng)常有香客問(wèn)我镊折,道長(zhǎng),這世上最難降的妖魔是什么介衔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任恨胚,我火速辦了婚禮,結(jié)果婚禮上炎咖,老公的妹妹穿的比我還像新娘赃泡。我一直安慰自己,他們只是感情好乘盼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布升熊。 她就那樣靜靜地躺著,像睡著了一般绸栅。 火紅的嫁衣襯著肌膚如雪级野。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天阴幌,我揣著相機(jī)與錄音勺阐,去河邊找鬼卷中。 笑死,一個(gè)胖子當(dāng)著我的面吹牛渊抽,可吹牛的內(nèi)容都是我干的蟆豫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼懒闷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼十减!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起愤估,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤帮辟,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后玩焰,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體由驹,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年昔园,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蔓榄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡默刚,死狀恐怖甥郑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情荤西,我是刑警寧澤澜搅,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站邪锌,受9級(jí)特大地震影響勉躺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜觅丰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一赂蕴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧舶胀,春花似錦概说、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至轩端,卻和暖如春放典,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工奋构, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留壳影,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓弥臼,卻偏偏與公主長(zhǎng)得像宴咧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子径缅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容