色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

workflow的任務模型

汽車電子技術 ? 來源: 程序喵大人 ? 作者: 程序喵大人 ? 2023-02-21 14:05 ? 次閱讀

今天,想聊聊workflow這個開源項目。

關于workflow,我之前特意寫過一篇文章【推薦學習這個C++開源項目】。

今天還是想再啰嗦啰嗦,因為自己這一年也在帶團隊從0到1做項目,需要負責整個項目的架構設計、接口設計、模塊劃分等工作。

做了一段時間后再回過頭復盤一下,深知架構設計、接口設計的重要性,也感受到了架構設計的困難程度,編碼和設計相比,真的容易的多了。

然后自己又回頭來研究了一下workflow,想著學習下其他項目的設計理念,隨著自己研究的越來越深入,越來越感覺它的高端,對外暴露特別簡單的接口卻能完成非常復雜的功能。

上篇文章是基礎篇,主要向大家普及一下workflow的特點和作用,感興趣的朋友可以移步到那里哈。

本篇文章是進階篇,主要就是想介紹下workflow的任務模型,其他的框架一般只能處理普通的網絡通信,而workflow卻特別適用于通信與計算關系很復雜的應用。其實我最感興趣的是它的內存管理機制,下面也會詳細介紹。

圖片

圖片

優秀的系統設計

圖片

圖片

在作者的設計理念中:程序 = 協議 + 算法 + 任務流。

**協議:**就是指通用的網絡協議,比如http、redis等,當然還可以自定義網絡協議,這里只需要提供序列化和反序列化函數就可以達到想要的效果。

算法: workflow提供了一些通用的算法,比如sort、merge、reduce等,當然還可以自定義算法,用過C++ STL的朋友應該都知道如何自定義算法吧,在workflow中,任何復雜的計算都應該包裝成算法。

**任務流:**我認為這應該就是整個系統設計的核心,通過任務流來抽象封裝實際的業務邏輯,就是把開發好的協議和算法組成一個任務流程圖,然后調度執行這個圖。

圖片

圖片

任務流

圖片

圖片

這里多聊聊任務流,在workflow中,一切業務邏輯皆是任務,多個任務會組成任務流,任務流可組成圖,這個圖可能是串聯圖,可能是并聯圖,也有可能是串并聯圖,類似于這種:

圖片

也可能是這種復雜的DAG圖:

圖片

圖的層次結構可以由用戶自定義,框架也是支持動態地創建任務流。

引用作者的一句話:

圖片

圖片

如果把業務邏輯想象成用設計好的電子元件搭建電路,那么每個電子元件內部可能又是一個復雜電路。

workflow對任務做了很好的抽象和封裝。整個系統包含6種基礎任務:通訊、文件IO、CPU定時器、計數器。

workflow提供了任務工廠,所有的任務都由任務工廠產生,并且會自動回收。

大多數情況下,通過任務工廠創建的任務都是一個復合任務,但用戶并不感知。例如一個http請求,可能包含很多次異步過程(DNS,重定向),內部有很多復雜的任務,但對用戶來講,這就是一次簡單的通信任務。

哪有什么歲月靜好,只不過是有人替你負重前行。workflow的一大特點就是接口暴露的特別簡潔,非常方便用戶的接入,外部接入如此簡單,肯定是將很多組合的邏輯都放在了內部,但其實workflow項目內部代碼結構層次非常簡潔清晰,感興趣的朋友可以自己研究研究哈。

圖片

圖片

內存管理機制

圖片

圖片

還有就是項目的內存管理機制,workflow整個項目都遵循著誰申請誰釋放的原則,內部申請的內存不需要外部顯式釋放,內部會自動回收內存。

而且整個項目都沒有使用shared_ptr,那多個對象共同使用同一塊裸內存,workflow是怎么處理的呢?

內部為這種需要共享的對象各自維護一個引用計數,手動incref和decref,至于為什么要這樣做,可以看看workflow美女架構師的回答【https://www.zhihu.com/question/33084543/answer/2209929271】。

我總結了一下:

  • shared_ptr是非侵入式指針,一層包一層,而且為了保持shared_ptr覆蓋對象整個生命周期,每次傳遞時都必須帶著智能指針模板,使用具有傳染性,而且也比較麻煩。
  • shared_ptr引用計數的內存區域和數據區域不一致,不連續,緩存失效可能導致性能問題,盡管有make_shared,但還是容易用錯。
  • 手動為對象做incref和decref,使用起來更靈活,可以明確在引用計數為固定數字時做一些自定義操作,而且方便調試。因為手動管理對象的引用計數,就會要求開發者明晰對象的生命周期,明確什么時候該使用對象,什么時候該釋放對象。
  • 如果使用shared_ptr可能會激起開發者的惰性,反正也不需要管理內存啦,就無腦使用shared_ptr唄,最后出現問題時調試起來也比較困難。

那再深入源碼中研究研究,看看workflow是如何做到把對象指針給到外部后,內部還自動回收的。

拿WFClientTask舉例說明一下,workflow中所有的Task都是通過Factory創建:

static WFHttpTask *create_http_task(const std::string& url,
                    int redirect_max,
                    int retry_max,
                    http_callback_t callback);


using WFHttpTask = WFNetworkTask;

template <class REQ, class RESP>
class WFClientTask : public WFNetworkTask {};

注意,create參數里有一個callback,workflow一定會執行這個callback,然后內部回收掉該WFClientTask占用的內存,任何任務的生命周期都是從創建到callback函數結束。

它是怎么做到的?繼續看下WFClientTask的繼承層次結構:

template <class REQ, class RESP>
class WFClientTask : public WFNetworkTask {};


template<class REQ, class RESP>
class WFNetworkTask : public CommRequest {};


class CommRequest : public SubTask, public CommSession {};


class SubTask {
public:
  virtual void dispatch() = 0;
private:
  virtual SubTask *done() = 0;
protected:
  void subtask_done();
};

WFClientTask繼承于WFNetworkTask,WFNetworkTask又繼承于SubTask。

SubTask內部有subtask_done()方法,看下它的實現:

void SubTask::subtask_done() {
  SubTask *cur = this;
  ParallelTask *parent;
  SubTask **entry;


  while (1) {
    parent = cur->parent;
    entry = cur->entry;
    cur = cur->done();
    if (cur) {
      cur->parent = parent;
      cur->entry = entry;
      if (parent)
        *entry = cur;
      cur->dispatch();
    }
    else if (parent) {
      if (__sync_sub_and_fetch(&parent->nleft, 1) == 0) {
        cur = parent;
        continue;
      }
    }
    break;
  }
}

subtask_done()方法中會調用它的done()方法,然而這幾個方法都是virtual方法,看看WFClientTask是怎么重寫它們的:

template <class REQ, class RESP>
class WFClientTask : public WFNetworkTask<REQ, RESP> {
protected:
  virtual SubTask *done() {
    SeriesWork *series = series_of(this);
    if (this->state == WFT_STATE_SYS_ERROR && this->error < 0) {
      this->state = WFT_STATE_SSL_ERROR;
      this->error = -this->error;
    }
    if (this->callback)
      this->callback(this);
    delete this;
    return series->pop();
  }
};

子類重寫了done()方法,可以看到在它的實現里,觸發了callback,然后調用了delete this,釋放掉了當前占用的這塊內存。

那誰調用的done(),可以看下上面的代碼,subtask_done()會觸發done(),那誰觸發的subtask_done():

void CommRequest::dispatch() {
  if (this->scheduler->request(this, this->object, this->wait_timeout,
                 &this->target) < 0) {
    this->state = CS_STATE_ERROR;
    this->error = errno;
    if (errno != ETIMEDOUT)
      this->timeout_reason = TOR_NOT_TIMEOUT;
    else
      this->timeout_reason = TOR_WAIT_TIMEOUT;
    this->subtask_done();
  }
}

可以看到,dispatch()里觸發了subtask_done(),那誰觸發的dispatch():

template<class REQ, class RESP>
class WFNetworkTask : public CommRequest {
public:
  /* start(), dismiss() are for client tasks only. */
  void start() {
    assert(!series_of(this));
    Workflow::start_series_work(this, nullptr);
  }
};


inline void
Workflow::start_series_work(SubTask *first, SubTask *last,
              series_callback_t callback) {
  SeriesWork *series = new SeriesWork(first, std::move(callback));
  series->set_last_task(last);
  first->dispatch();
}

這里可以看到,Task的start()方法觸發start_series_work(),進而觸發dispatch()方法。

總結一下:

● 步驟一

通過工廠方法創建WFClientTask,同時設置callback;

● 步驟二

外部調用start()方法,start()中調用Workflow::start_series_work()方法;

● 步驟三

start_series_work()中調用SubTask的dispatch()方法,這個dispatch()方法由SubTask的子類CommRequest(WFClientTask的父類)實現;

● 步驟四

dispatch()方法在異步操作結束后會觸發subtask_done()方法;

● 步驟五

subtask_done()方法內會觸發done()方法;

● 步驟六

done()方法內會觸發callback,然后delete this;

● 步驟七

內存釋放完成。

其實這塊可以猜到,想要銷毀自己的內存,基本上也就delete this這個方法。

然而我認為這中間調用的思想和過程才是我們需要重點關注和學習的,遠不止我上面描述的這么簡單,感興趣的朋友可以自己去研究研究哈。

關于workflow還有很多優點,這里就不一一列舉啦,它的源碼也值得我們CPP開發者學習和進階,具體可以看我之前的文章。

發現workflow團隊對這個項目相當重視,還特意建了個QQ交流群(群號碼是618773193),對此項目有任何問題都可以在這個群里探討,也方便了我們學習,真的不錯。項目地址如下:https://github.com/sogou/workflow,也可以點擊閱讀原文直達。

在訪問GitHub遇到困難時,可使用他們的Gitee官方倉庫:https://gitee.com/sogou/workflow。

項目也特別實用,據說搜狗內外很多團隊都在使用workflow。感覺這個項目值得學習的話就給人家個star,不要白嫖哈,對項目團隊來說也是一種認可和鼓勵。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 框架
    +關注

    關注

    0

    文章

    403

    瀏覽量

    17475
  • 網絡通信
    +關注

    關注

    4

    文章

    797

    瀏覽量

    29795
  • workflows
    +關注

    關注

    0

    文章

    6

    瀏覽量

    5926
收藏 人收藏

    評論

    相關推薦

    老生常談---一種裸奔多任務模型

    一種裸奔多任務模型一個網友的總結:stateMachine + timerTick + queue。在RTOS環境下的多任務模型任務通常阻塞在一個OS調用上(比如從消息隊列取數據)。外部如果想讓該
    發表于 12-08 10:13

    裸奔環境下的多任務模型

    對于簡單的嵌入式應用多數裸奔就能解決,但寫出來的裸奔代碼質量也由好壞之分。在網上看到了這樣一篇文字:上面說到了裸奔環境下的多任務模型 - stateMachine + timerTick
    發表于 01-21 07:41

    allegro中workflow manager求解

    allegro中analysis菜單下使用workflow manager,點擊start analysis后顯示implement analysis failed或者coupling analysis failed?
    發表于 03-07 22:02

    Stage模型深入解讀

    基于Stage模型開發應用,下面將會從應用組件、進程模型、線程模型任務模型、后臺運行機制、應用配置文件6個方面進行介紹。 1、組件模型
    發表于 03-15 10:32

    OPC 實時任務系統動態調度算法的研究與設計The Stud

    本文基于已有的OPC Server 實時任務模型,設計了處理混合任務集的動態調度算法(基于截止期優先)和實現方式。該算法實現了對混合任集可調度性的判斷,可以完成有硬實時性要
    發表于 05-31 15:36 ?13次下載

    一種基于角色和任務的訪問控制模型

    在基于角色的訪問控制模型的基礎上引入了任務(task)和任務實例(task instance)的概念,建立了基于角色和任務的訪問控制模型(R
    發表于 08-05 16:30 ?8次下載

    控制系統中實時任務分析

    本文分析了控制系統任務的特點,給出了控制系統中各種實時任務模型。分析了控制系統性能與任務參數之間的關系,給出了參數的設置方法。最后,研究了控制系統中實時任務
    發表于 08-06 08:35 ?10次下載

    基于頁的8051多任務模型

      隨著8051微控制器性能的不斷提高,使用多任務操作系統對單片機進行資源管理已成為當代開發的需要。由于受靜態鏈接的限制,8051系統的多任務開發需要處理代碼重入(reentran
    發表于 09-25 17:34 ?971次閱讀
    基于頁的8051多<b class='flag-5'>任務模型</b>

    基于改進蜂群算法的多維QoS云計算任務調度算法

    針對云計算環境下用戶日益多樣化的QoS需求和高效的資源調度要求,提出了基于改進蜂群算法的多維QoS云計算任務調度算法,其中包括構建任務模型、云資源模型和用戶QoS模型。為了獲得高效的調
    發表于 12-01 16:11 ?0次下載

    嵌入式多核處理器任務調度研究

    任務模型而選擇粒子群算法的適應度函數,綜合利用局部最優極值和全局最優極值的優勢,優化了粒子群算法中存在的過早收斂問題,使算法具有較高的收斂效率。實驗結果表明,與基于遺傳算法的多核多線程任務調度算法相比,該算法
    發表于 01-17 17:49 ?1次下載
    嵌入式多核處理器<b class='flag-5'>任務</b>調度研究

    一種基于神經網絡的聯合識別方法

    從事件時序關系與因果關系的關聯性出發,提出基于神經網絡的聯合識別方法。將時序關系和因果關系識別分別作為主任務和輔助任務,設計共享輔助任務中編碼層、解碼層和編解碼層的3種聯合識別模型,通
    發表于 03-25 15:47 ?11次下載
    一種基于神經網絡的聯合識別方法

    開源軟件-Sogou C++ Workflow高性能C++服務器引擎

    ./oschina_soft/gitee-workflow.zip
    發表于 06-20 09:36 ?1次下載
    開源軟件-Sogou C++ <b class='flag-5'>Workflow</b>高性能C++服務器引擎

    模型任務的評價指標體系

    1. 寫在前面 模型“好”與“壞”的評價指標直接由業務目標/任務需求決定。我們需要做的是:根據具體的業務目標/任務需求去選擇相應的評價指標,繼而選出符合業務目標/任務需求的好
    的頭像 發表于 01-11 10:10 ?861次閱讀

    基于M55H的定制化backbone模型AxeraSpine

    Backbone模型是各種視覺任務訓練的基石,視覺任務模型的性能和模型的速度都受backbone模型的影響
    的頭像 發表于 10-10 16:09 ?954次閱讀
    基于M55H的定制化backbone<b class='flag-5'>模型</b>AxeraSpine

    workflow異步任務調度編程范式

    workflow是一個異步任務調度編程范式,封裝了6種異步資源:CPU計算、GPU計算、網絡、磁盤I/O、定時器、計數器,以回調函數模式提供給用戶使用,概括起來實際上主要是兩個功能:1、屏蔽阻塞調用的影響,使阻塞調用的開發接口變為異步的,充分利用計算資
    的頭像 發表于 11-09 09:42 ?507次閱讀
    <b class='flag-5'>workflow</b>異步<b class='flag-5'>任務</b>調度編程范式
    主站蜘蛛池模板: 亚洲精品欧美精品中文字幕| 青青青视频在线| 久久中文字幕无线观看| 巨胸美女狂喷奶水www网麻豆| 久久中文电影| 免费播放美女一级毛片| 秋霞在线观看视频一区二区三区| 色多多涩涩屋下载软件| 羞羞漫画免费漫画页面在线看漫画秋蝉| 亚洲 日韩 欧美 国产专区| 亚洲视频在线免费| 4388成人| 成人在线高清不卡免费视频| 国产精品视频yy9099| 精品国产免费第一区二区| 美国女孩毛片| 日本漂亮妈妈7观整有限中| 新版孕妇bbwbbwbbw| 在公交车上被JB草坏了被轮J了| 91精品国产色综合久久不| 大肥女ass樱桃| 狠狠人妻久久久久久综合九色| 恋夜影院支持安卓视频美女| 欧美亚洲高清国产| 亚洲 日本 中文字幕 制服| 91精品国产色综合久久不| 国产成人免费a在线资源| 第一次破女初国产美女| old老男人野外树林tv| 国产精品夜夜春夜夜爽久久小| 久久er99热精品一区二区| 欧美嫩freexxxhddvd| 亚洲AV永久无码精品老司机蜜桃| 2020国产成人精品免费视频| 高清无码中文字幕影片| 久久99精国产一区二区三区四区| 欧美怡红院视频一区二区三区| 性生大片免费看| www在线小视频免费| 饥渴的新婚女教师| 国产午夜精品一区理论片飘花 |