Actor 模型 / CSP模型 / 共享內存模型

 

CSP模型 通訊順序進程,其實就是基於channel的消息通訊,在ROS中,這種channel稱做主題topichtml

erlangactor的表明性語言,goCSP的表明性語言python

 

還有幾個沒怎麼看的答案,不過都差很少了,這個講歷史比較多,也比較透徹,頗有用,須要再仔細看!git

https://stackoverflow.com/questions/22621514/is-scalas-actors-similar-to-gos-coroutines/22622880?r=SearchResults#22622880程序員

https://stackoverflow.com/questions/20171442/is-communicating-sequential-processes-csp-an-alternative-to-the-actor-model-in?r=SearchResultsgithub

http://en.wikipedia.org/wiki/Communicating_sequential_processes#Comparison_with_the_Actor_Model編程

理解ACTOR和CSP模型,有python源碼。多線程

https://www.codercto.com/a/9890.html併發

 

Actor 模型與Object模型框架

Theron框架是一個基於Actor模型的併發編程的C++庫。而Actor模型使得Theron框架能夠直接有效的建立並行分佈式的應用。Theron框架提供了不少輕量便攜的函數接口API,可使用在LinuxWindowsMacARMMatlab環境。 異步

咱們知道面向對象編程中使用的是Object模型,宣揚一切皆是對象,數據+行爲=對象。而Actor模型則認爲一切皆是Actor,Actor模型內部的狀態由本身的行爲維護,外部線程不能直接調用對象的行爲,必須經過消息才能激發行爲,也就是使用消息傳遞機制來代替Object模型的成員方法的調用,這樣就保證Actor內部數據只能被本身修改。Actor模型=數據+行爲+消息。 

可是C++是一種面向對象的語言,因此最終仍是經過類來封裝這種actor的機制,多線程的實現也是依靠內存共享的多線程機制設計的,只不過這些事情Theron源碼已經幫咱們完成了,咱們直接使用它給出的類接口便可。Theron框架的多線程基礎支持pthreads,Windows threads,boost::thread和C++11 threads四種傳統類型來構建。多說一嘴,由於Theron框架在C++中說到底仍是經過類封裝實現Actor模型的,天然咱們直接經過類對象調用類中方法數據。可是爲了保證Theron框架生態的完整性,而且真正體現actor模型的優越性,咱們仍是不要如此爲好。 

基於Object模型與Actor模型區別如圖3所示。

 

 

这里写图片描述

(a) 

 

这里写图片描述

(b) 

圖3 基於Object機制與基於Actor機制的比較 

從圖中能夠看到,類A的對象成員方法調用類B的對象成員方法須要通過A::call調用B::called方法,而後等待B::called方法執行完成而且返回響應,最後A::call繼續上次調用的地方後面執行下去。而在Actor模型中,Actor A先發送消息給Actor B,而後即刻就返回繼續執行下面的程序,而Actor B中收到消息被喚醒和Actor A並行執行下去。 

至此,Actor模型就能夠看出這種消息機制的線程調用最大好處是非阻塞的,多個線程能夠同時併發進行,無需等待被調用方法執行完成返回消息的響應。固然,看到此處你們或許跟我同樣有一點困惑的地方,即萬一咱們後面的程序須要當即使用它返回的響應消息怎麼辦呢?其實這也算Actor存在的一點不足之處,須要咱們在設計多線程前考慮你的程序到底適不適合這種機制,後面咱們會再詳細描述。 

--------------------- 

做者:無鞋童鞋 

來源:CSDN 

原文:https://blog.csdn.net/FX677588/article/details/74359823 

版權聲明:本文爲博主原創文章,轉載請附上博文連接!

 

3.2 Actor模型與共享內存模型不一樣點 

Actor這種獨立併發的模型,與另外一種共享內存模型徹底相反。Actor之間經過消息傳遞方式進行合做,相互線程獨立。隨着多核時代和分佈式系統的到來,共享內存模型其實不適合開發的。咱們以酒店廚房作菜爲例,如圖4所示。

 

 

这里写图片描述

圖4 Actor模型與共享內存模型的比喻圖示

 

①、單線程編程,如圖4(a)——猶如酒店只有一個廚師員工(一個線程),全部菜按點菜順序與工序完成到底就行; 

②、共享內存的多線程編程,如圖4(b)——猶如酒店廚房是由洗菜工,刀工,掌勺,服務員等(每一個人是一個線程),他們之間的確能經過合做能比一個廚師完成全部工序要快。咱們須要考慮的是菜至關因而他們共享的資源,每次只能一我的在對其作處理,雖然有多道菜品,可是總會在穿插間存在等待。 

③、Actor模型的多線程編程,如圖4(c)——猶如酒店有多個廚師,分別是川菜師傅,魯菜師傅,徽菜師傅等等,他們只要接到客人點菜的需求,整我的獨自完成相對應菜系的工序,之間無論對方師傅要幹嗎,如此多線程工做就大大增長了效率,而且不存在互相等待資源的狀況,作好了本身發消息給服務員端菜便可。 

這樣咱們就能夠看出Actor模型異步消息傳遞來觸發程序並行執行,雖然不如直接調用來的直接而方便,可是它可讓大量消息真正意義上同步執行。同時消息讓Actor之間解耦,消息發出去以後執行成功與否,耗時多少等等只要沒有消息傳遞回來,一切都不在與發送方有任何關聯。這樣也保證了,咱們不須要在共享環境中與同步鎖,互斥體等經常使用基礎多線程元素打交道。 

--------------------- 

做者:無鞋童鞋 

來源:CSDN 

原文:https://blog.csdn.net/FX677588/article/details/74359823 

版權聲明:本文爲博主原創文章,轉載請附上博文連接!

 

 

這篇文章講解了如何使用netmq來實現個簡單的actor,同時也講解了actor model的基本概念,與共享內存模型的區別

https://github.com/zeromq/netmq/blob/master/docs/actor.md

 

actor模型與CSP模型

https://www.jdon.com/concurrent/actor-csp.html

 

臥槽,ROS的主題就是CSP模型中的CHANNEL!!!

Actor模型和CSP模型的區別

Akka/Erlangactor模型與Go語言的協程Goroutine與通道Channel表明的CSP(Communicating Sequential Processes)模型有什麼區別呢?

首先這二者都是併發模型的解決方案,咱們看看Actor和Channel這兩個方案的不一樣:

Actor模型

在Actor模型中,主角是Actor,相似一種worker,Actor彼此之間直接發送消息,不須要通過什麼中介,消息是異步發送和處理的:

actor模型

Actor模型描述了一組爲了不併發編程的常見問題的公理:

1.全部Actor狀態是Actor本地的,外部沒法訪問。

2.Actor必須只有經過消息傳遞進行通訊。

3.一個Actor能夠響應消息:推出新Actor,改變其內部狀態,或將消息發送到一個或多個其餘參與者。

4.Actor可能會堵塞本身,Actor不該該堵塞它運行的線程。

更多可見Actor模型專題

 

Channel模型

Channel模型中,worker之間不直接彼此聯繫,而是經過不一樣channel進行消息發佈和偵聽。消息的發送者和接收者之間經過Channel鬆耦合,發送者不知道本身消息被哪一個接收者消費了,接收者也不知道是哪一個發送者發送的消息。

channel模型

Go語言的CSP模型是由協程Goroutine與通道Channel實現:

  • Go協程goroutine: 是一種輕量線程,它不是操做系統的線程,而是將一個操做系統線程分段使用,經過調度器實現協做式調度。是一種綠色線程,微線程,它與Coroutine協程也有區別,可以在發現堵塞後啓動新的微線程。
  • 通道channel: 相似Unix的Pipe,用於協程之間通信和同步。協程之間雖然解耦,可是它們和Channel有着耦合。

 

Actor模型和CSP區別

Actor模型和CSP區別圖以下:

ErIang  в

Actor之間直接通信,而CSP是經過Channel通信,在耦合度上二者是有區別的,後者更加鬆耦合。

同時,它們都是描述獨立的流程經過消息傳遞進行通訊。主要的區別在於:在CSP消息交換是同步的(即兩個流程的執行"接觸點"的,在此他們交換消息),而Actor模型是徹底解耦的,能夠在任意的時間將消息發送給任何未經證明的接受者。因爲Actor享有更大的相互獨立,由於他能夠根據本身的狀態選擇處理哪一個傳入消息。自主性更大些。

在Go語言中爲了避免堵塞流程,程序員必須檢查不一樣的傳入消息,以便預見確保正確的順序。CSP好處是Channel不須要緩衝消息,而Actor理論上須要一個無限大小的郵箱做爲消息緩衝。

http://www.javashuo.com/article/p-rpposmvt-hb.html

源於從Erlang到Go的一些思惟碰撞,就像當初從C++到Erlang同樣,整理下來記於此。

Actor

Actor模型,又叫參與者模型,其」一切皆參與者(actor)」的理念與面向對象編程的「一切皆是對象」相似,可是面向對象編程中對象的交互一般是順序執行的(佔用的是調用方的時間片,是否併發由調用方決定),而Actor模型中actor的交互是並行執行的(不佔用調用方的時間片,是否併發由本身決定)

在Actor模型中,actor執行體是第一類對象,每一個actor都有本身的ID(類比人的身份證),能夠被傳遞。actor的交互經過發送消息來完成,每一個actor都有一個通訊信箱(mailbox,本質上是FIFO消息隊列),用於保存已經收到但還沒有被處理的消息。actorA要向actorB發消息,只需持有actorB ID,發送的消息將被當即Push到actorB的消息信箱尾部,而後返回。所以Actor的通訊原語是異步的。

從actor自身來講,它的行爲模式可簡化爲:

  • 發送消息給其它的actor
  • 接收並處理消息,更新本身的狀態
  • 建立其它的actor

一個好的Actor模型實現的設計目標:

  • 調度器: 實現actor的公平調度
  • 容錯性: 具有良好的容錯性和完善錯誤處理機制
  • 擴展性: 屏蔽actor通訊細節,統一本地actor和遠程actor的通訊方式,進而提供分佈式支持
  • 熱更新? (還沒弄清楚熱更新和Actor模型,函數式範式的關聯性)

在Actor模型上,Erlang已經耕耘三十餘載,以上提到的各個方面都有很是出色的表現,其OTP整合了在Actor模型上的最佳實踐,是Actor模型的標杆。

CSP

順序通訊進程(Communicating sequential processes,CSP)和Actor模型同樣,都由獨立的,併發的執行實體(process)構成,執行實體間經過消息進行通訊。但CSP模型並不關注實體自己,而關注發送消息使用的通道(channel),在CSP中,channel是第一類對象,process只管向channel寫入或讀取消息,並不知道也不關心channel的另外一端是誰在處理。channel和process是解耦的,能夠單首創建和讀寫,一個process能夠讀寫(訂閱)個channel,一樣一個channel也可被多個process讀寫(訂閱)。

對每一個process來講:

  • 從命名channel取出並處理消息
  • 向命名channel寫入消息
  • 建立新的process

Go語言並無徹底實現CSP理論(參見知乎討論),只提取了CSPprocesschannel的概念爲併發提供理論支持。目前Go已是CSP的表明性語言。

CSP vs Actor

  • 相同的宗旨:」不要經過共享內存來通訊,而應該經過通訊來共享內存」
  • 二者都有獨立的,併發執行的通訊實體
  • Actor第一類對象爲執行實體(actor)CSP第一類對象爲通訊介質(channel)
  • Actor中實體和通訊介質是緊耦合的,一個Actor持有一個Mailbox,而CSPprocesschannel是解耦的,沒有從屬關係。從這一層來講,CSP更加靈活
  • Actor模型中actor是主體,mailbox是匿名的,CSP模型中channel是主體,process是匿名的。從這一層來講,因爲Actor不關心通訊介質,底層通訊對應用層是透明的。所以在分佈式和容錯方面更有優點

Go vs Erlang

  • 以上 CSP vs Actor
  • 均實現了語言級的coroutine,在阻塞時能自動讓出調度資源,在可執行時從新接受調度
  • gochannel是有容量限制的,所以只能必定程度地異步(本質上仍然是同步的)erlangmailbox是無限制的(也帶來了消息隊列膨脹的風險),而且erlang並不保證消息是否能到達和被正確處理(但保證消息順序),是純粹的異步語義,actor之間作到徹底解耦,奠基其在分佈式和容錯方面的基礎
  • erlang/otpactor上擴展了分佈式(支持異質節點),熱更和高容錯,go在這些方面還有一段路要走(受限於channel,想要在語言級別支持分佈式是比較困難的)
  • go在消息流控上要作得更好,由於channel的兩個特性: 有容量限制並獨立於goroutine存在。前者能夠控制消息流量並反饋消息處理進度,後者讓goroutine自己有更高的處理靈活性。典型的應用場景是扇入扇出,Boss-Worker等。相比goerlang進程老是被動低處理消息,若是要作流控,須要本身作消息進度反饋和隊列控制,靈活性要差不少。另一個例子就是erlangreceive操做須要遍歷消息隊列(參考),而若是用go作同步調用,經過單獨的channel來作則更優雅高效

Actor in Go

在用Go寫GS框架時,不自覺地會將goroutine封裝爲actor來使用:

  • GS的執行實體(如玩家,公會)的邏輯具有強狀態和功能聚合性,不易拆分,所以一般是一個實體一個goroutine
  • 實體接收的邏輯消息具有弱優先級,高順序性的特色,所以一般實體只會暴露一個Channel與其它實體交互(結合go的interface{}很容易統一channel類型),這個channel稱爲RPC channel,它就像這個goroutine的ID,幾乎全部邏輯goroutine之間經過它進行交互
  • 除此以外,實體還有一些特殊的channel,如定時器,外部命令等。實體goroutine對這些channel執行select操做,讀出消息進行處理
  • 加上goroutine的狀態數據以後,此時的goroutine的行爲與actor類似:接收消息(多個消息源),處理消息,更新狀態數據,向其它goroutine發送消息(經過RPC channel)

到目前爲止,goroutine和channel解耦的優點並未體現出來,我認爲主要的緣由仍然是GS執行實體的強狀態性和對異步交互流程的順序性致使的。

在研究這個問題的過程當中,發現已經有人已經用go實現了Actor模型: https://github.com/AsynkronIT/protoactor-go。 支持分佈式,甚至supervisor,總體思想和用法和erlang很是像,真是有種他山逢知音的感受。:)

參考:

  1. http://jolestar.com/parallel-programming-model-thread-goroutine-actor/
  2. https://www.zhihu.com/question/26192499

 

http://wudaijun.com/2017/05/go-vs-erlang/

//--------------------------------------------------------------------------------------------- 合抱之木,生於毫末;九層之臺,起於壘土;千里之行,始於足下。 積土成山,風雨興焉;積水成淵,蛟龍生焉;積善成德,而神明自得,聖心備焉。故不積跬步,無以致千里;不積小流,無以成江海。騏驥一躍,不能十步;駑馬十駕,功在不捨。鍥而舍之,朽木不折;持之以恆,金石可鏤。蚓無爪牙之利,筋骨之強,上食埃土,下飲黃泉,用心一也。蟹六跪而二螯,非蛇鱔之穴無可寄託者,用心躁也。

相關文章
相關標籤/搜索