CAF(C++ Actor Framework)介紹

一. 描述.


caf是一個actor模型的開源編程框架,  強c++11風格的實現, 早先的名字並不叫CAF, 而是CPPA. 改名的時間發生在版本(0.9 >> 0.10). 而最近的版本

是0.11.2, 從文檔上看, caf的實現參考了akka和erlang.  默認的actor調度是基於線程池方式, 而不是協程. 因此更像akka. 由於caf是基於c++的實現, 

在性能上可能更佔優勢.  更讓人無法拒絕的是在caf中大量使用了lambda表達式來替換通常散落一地的回調函數.  視覺上非常直觀, 開發時可以少

死很多腦細胞.  當然這個項目現在還非常新, 網絡io部分也比較瘦, 養肥了再用到生產環境中不遲.


二. caf的主要特性


1. actor

actor分爲兩種, 無類型actor和強類型actor. actor的創建非常簡單, 簡單到不能再簡單了, 如下面的例子. 將一個自由函數作爲參數傳遞spawn, 

一個actor就生成了, 在下面的例子中actorx內部持有一個actor的句柄self. 所有與這個actor有關的消息都從這裏開始.

void actorx(event_based_actor* self)
{

}
spawn(actorx);

2. 模式匹配.

模式匹配是caf中一個十分重要的特性, 它直接導致了caf基於lambda表達式的消息回調列表成爲可能. caf爲此自己內建了DSL語言來達成這個目的.

下面效果就是來自模式匹配.

void actorx(event_based_actor* self)
{
    self->become(	
    [=](const string& what)
    {
        LOG_DEBUG("got a string msg: %s\n", what.c_str())
    },
    [=](const int& what)
    {
	    LOG_DEBUG("got integer msg: %d\n", what)
    });
}
auto a = spawn(actorx);
anon_send(a, "string"); /* 向actor發送一個字符串. */
anon_send(a, 0x10); /* 向actor發送一個整數. */
需要說明的是, 上面的例子中actorx函數是立即返回的, 也就是說裏面的become也是立即返回的,  好像把兩個消息處理回調放在actorx函數內部.

當有消息到來時, 經模式匹配後就會調用恰當的lambda表達式.  不用再到處找回調了.


3. 消息發送.

消息發送可以分爲以下幾種:

a). 發完就忘, 就像上面anon_send.

b). 同步發送, 等待響應. 等待是異步的, 相當於只是期待一個響應.

c). 同步發送, 等待響應, 超時後收到一個系統消息.

d). 同步發送, 同步等待. 適用阻塞的actor api.

e). 消息延遲發送, 這一點比akka做得漂亮很多.

 f). 消息前轉, forward.

g). 消息優先級選擇.


4. 消息接收.

主要有兩種特性:

a). 等待超時, 超時後收到一個系統消息.

b). 消息跳過, skip.


5. 行爲(behavior)

如果actor的消息流程是一個有限狀態機, 那行爲就是用來控制流程的標誌. behavior是一個棧, 通過keep_behavior壓棧, unbecome恢復.


6.  鏈接(link)

兩個(或多個)actor可以相互link在一起, 生死相關. 一起活着或者默認一起死去. 

當其中一個actor異常退出時, 另一個(可能是多個)會收到一個"exit_msg"消息, 如果不捕獲這個消息. 默認的行爲就是當前actor也退出.

如果選擇捕獲, 那就自己定義行爲.


7. 監視(monitor)

一個actor可選擇監視另一個或另幾個actor. 甚至可以同時監視同一個actor多次. 當被監視的actor退出時, 監視者就會收到一個"down_msg". 

監視者僅僅是收到這個消息而已. 不會有其它對自己的響應. 需自己定義行爲. 


8. 在網絡上發佈一個actor.

這個功能貌似還非常骨感, 其做法是調用pubish函數將一個actor綁定在某個本地端口上, 作爲服務器向外提供服務. 如下面的端口8080, 端口

後面還有一個默認的字符串參數, 允許指定本地服務ip.

auto a = spawn(actorx);
publish(a, 8080);
//
actor r = remote_actor("127.0.0.1", 8080);
anon_send(r, "information");
上面的remote_actor則用於連上publish的actor, 這樣分佈在不同機器上的actor就可以互相通信了. 這個功能似乎僅限於此了. 從實際的代碼運

行來看.  作爲服務器的actor只能收到客戶端發送的業務消息,  包括連接到來, 斷開等事件都無消息通知. 並且雙方之間的通信似乎還遵循某種協

議(自己寫一個socket, 向服務器發送消息時, 它無動於衷). 


9. 代理(broker)
broker的功能要比publish更強.  有點類似於我的前一篇博客中介紹的akka.io. 

比akka有一點好的地方在是, broker提供了有限的手動控制消息緩衝區的api.  

相信過不了多久. 用broker作服務器就會成爲不錯的選擇.


10.  組通信.

組可以分爲匿名組, 本地組和遠程組.  前兩個用於進程內通信, 遠程組則可能適合一些分佈式的應用場景. 一個actor可以加入或選擇離開組. 


三. 編譯.


項目地址是: https://github.com/actor-framework/actor-framework

簽出: git clone https://github.com/actor-framework/actor-framework.git 

編譯使用的是cmake, 過程很簡單, 沒什麼可說的.  編譯完之後, 會生成兩個庫, libcaf_core.so和libcaf_io.so. 如果你不打算使用網絡相關的功

能, 只要鏈接上libcaf_core就可以了.


四.  文檔


我翻譯了一個libcaf的手冊, 上傳到百度文庫了. 草稿, 無任何保證質量. 如下:

http://wenku.baidu.com/view/7e2b6be16529647d2728528e.html

原文地址: http://www.actor-framework.org/manual/




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章