Actor併發編程模型淺析

来源:https://www.cnblogs.com/listenfwind/archive/2018/11/16/9963489.html
-Advertisement-
Play Games

一.Actor模型介紹 在單核 CPU 發展已經達到一個瓶頸的今天,要增加硬體的速度更多的是增加 CPU 核的數目。而針對這種情況,要使我們的程式運行效率提高,那麼也應該從併發方面入手。傳統的多線程方法又極其容易出現 Bug 而難以維護,不過別擔心,今天將要介紹另一種併發的模式能一定程度解決這些問題 ...


一.Actor模型介紹

在單核 CPU 發展已經達到一個瓶頸的今天,要增加硬體的速度更多的是增加 CPU 核的數目。而針對這種情況,要使我們的程式運行效率提高,那麼也應該從併發方面入手。傳統的多線程方法又極其容易出現 Bug 而難以維護,不過別擔心,今天將要介紹另一種併發的模式能一定程度解決這些問題,那就是 Actor 模型。

Actor 模型其實就是定義一組規則,這些規則規定了一組系統中各個模塊如何交互及回應。在一個 Actor 系統中,Actor 是最小的單元模塊,系統由多個 Actor 組成。每個 Actor 有兩個東西,一個是 mailbox,一個是自身狀態。同時 Actor 有接收和發送的功能。下麵代碼給出一個大概的 Actor 樣例:

trait Actor {
  //持有一個表示自身狀態的私有變數
  val state:Integer = 0;
  //持有一個mailbox 的隊列
  val mailBox:mutable.Queue[Message] = scala.collection.mutable.Queue[Message]()
  def send(message : Message): Unit ={
      ...
  }
  def recive(): Unit ={
      ...
  }
}

當一個 Actor 接收到消息後,它會執行下麵三種操作中的一種:

  • 創建其他actors。
  • 向其他actors發送消息。
  • 修改自身狀態。
    需要註意的是,儘管許多actors同時運行,但是一個actor只能順序地處理消息。也就是說其它actors發送了三條消息給一個actor,這個actor只能一次處理一條。所以如果你要並行處理3條消息,你需要把這條消息發給3個actors。

下麵這張圖展示了一個簡單的 Actor 模型系統:

瞭解了 Actor 模型的大概規則後,我們用兩個具體的例子來看看 Actor 模型的妙處以及不足吧。

二. 兩個例子

2.1 素數計算

假設我們現在有一個任務,需要找出100000以內素數個數,並且使用多線程的方式實現。

下圖展示了使用共用記憶體的方式和以Actor模型的方式進行併發執行。
Actor 素數計算

這裡展示了兩種處理併發的不同思路,傳統的方式是通過鎖/同步的方式來實現併發,每次同步獲取當前值,並讓一個線程去判斷值是否為素數,是的話再通過同步的方式對計數器加1(這裡的說明只是作為提供思路用,這種方法自然有很大的優化空間)。

而使用 Actor 模型則不一樣,它將這一過程拆分成幾個模塊,即拆分成幾個 Actor 。每個 Actor 負責不同的部分,通過消息傳遞的方式讓這幾個 Actor 協同工作,並且其中涉及到主要計算的 Actor 可以有多個,通過多個 Actor 協同工作實現併發。

2.2 銀行轉賬

銀行轉賬的任務描述很簡單,假設有兩個用戶,現在用戶A向用戶B轉賬100元,這個 Actor 模型該如何設計呢?

用戶 A 和 用戶 B 明顯是兩個 Actor ,但我們同時還需要一個可以控制用戶A Actor 和用戶B Actor 的 Actor ,我們稱之為 轉賬管家 Actor。那麼流程圖如下。
Actor 銀行轉賬

可以看到,當一個轉賬需求過來的時候,Actor 管家會先向 用戶A Actor 發送扣款 100 元的信息,接受到扣款成功消息後再發送消息給用戶B Actor,發送讓其增加 100 元的消息。

一切看起來都很美好是吧,但這裡面有一個問題,那就是在用戶A Actor 扣款期間,用戶B Actor 是不受限制的,此時對用戶B Actor 進行操作是合法的!針對這種情況單純的Actor模型就顯得比較乏力了,需要加入其他機制以保證一致性。

看到這你就明白了,Actor 模型並非萬能的,它有一定的缺點。那就是針對一致性要求比較強的場景比較乏力。

三. 為什麼會出現 Actor 模型

接下來我們來聊聊為什麼會有 Actor 模型這種併發編程模型出現。

我們需要先說說併發性中的一致性隔離性

一致性即讓數據保持一致,比如銀行轉賬例子中,用戶A 轉給 用戶B 100塊錢,沒有其他干擾的情況下,轉賬完成時。用戶A 的賬戶必然減少 100 元,用戶B 的賬戶必然增加100 元,這就滿足了一致性。不能說用戶A 減少50 或用戶B 增加了 200。

隔離性可以理解為犧牲一部分的一致性需求,而獲得性能的提高。打個比方,在完全一致的情況下,任務都是串列的,這時候也就不存在隔離性了。

明白這些之後,你就直到為什麼會有 Actor 模型了。

傳統併發模式,共用記憶體是傾向於強一致性弱隔離性的。比如悲觀鎖/同步的方式,其實就是使用強一致性的方式控制併發。而Actor 模型天然是強隔離性且弱一致性,所以 Actor 模型在併發中有良好的性能,且易於控制和管理。

這樣你就明白 Actor 模型適合於什麼樣的併發場景了,當對一致性需求不是很高的情況下且對性能需求較高時,Actor 模型無疑是一個值得嘗試的方案。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在C語言中,有三種類型的迴圈語句:for語句、while語句和do While語句。分別介紹如下: 摺疊 for for為當型迴圈語句,它很好地體現了正確表達迴圈結構應註意的三個問題: ⑴控制變數的初始化。 ⑵迴圈的條件。 ⑶迴圈控制變數的更新。 for表達式 表達式1:一般為賦值表達式,給控制變數 ...
  • 一、javaScript中如何檢測一個變數是 String 類型: 1. typeto(obj) "srting" 2. typeTo obj "string" 3. obj.constructor string 二、用js去除字元串空格的方法? 1. 使用正則匹配的方式: a: str = str ...
  • 函數聲明: 1.顧名思義,聲明一個函數, 用關鍵字 “function” 來告訴,這是一個函數。 2.任何地方,想用就可以拿過來使用 函數表達式: 表達式, 最先想到的賦值表達式,如 a = b; 1.表達式與聲明的區別之一, 末尾有無 分號(;) 結束。 2.表達式不同於聲明的區別之二: 函數表達 ...
  • html5手機瀏覽器啟動微信客戶端支付實例,外部瀏覽器html5微信支付技術,如何在手機瀏覽器微信支付,在微信客戶端外的移動端網頁使用微信支付 首先在微信支付官網https://pay.weixin.qq.com/【我的產品】申請h5支付,免費申請的哦,很快就可以下來。 若出現上方截圖說明您申請h5 ...
  • JavaScript基礎(一) JavaScript是一種弱類型的腳本語言;根據賦值決定變數的類型 var a = 3; (變數聲明之前必須用var聲明,編程規範!) 變數的命名規範 變數聲明 全局變數 : 1.在方法外部聲明的變數 2.方法內部,沒有加var關鍵字聲明的變數 局部變數 1.方法內部 ...
  • 內置對象,宿主對象,自定義對象的區別? 內置對象: 系統所提供的對象:Object,Array,Math,Date等等。 宿主對象: JS所運行的環境提供的對象:BOM中的window,DOM中的document 自定義對象: 自定義構造函數所創建的對象 。 Array類型對象: 數組創建方式: 方 ...
  • 設計模式很重要,重要性我就不再覆述了。最主要的是,通常我們在寫一定量代碼後,常用的方法什麼的都熟悉後,想再提高代碼能力,我找到的最好的方法還是去學習,理解設計模式。不理解設計模式,看一些開源框架和java源碼會很難懂。 剛學java時就從各種文章,也聽很多人說面向對象編程很重要。但是在編程時雖然會建 ...
  • 安裝 SmartSql.ZooKeeperConfig Demo 工具使用 "ZooKeeper Admin" ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...