亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解為什么現(xiàn)代系統(tǒng)需要一個新的編程模型

 更新時間:2021年05月20日 11:02:42   作者:華為云開發(fā)者社區(qū)  
如今高要求的分布式系統(tǒng)的建造者遇到了不能完全由傳統(tǒng)的面向?qū)ο缶幊?OOP)模型解決的挑戰(zhàn),但這可以從Actor模型中獲益。

為什么現(xiàn)代系統(tǒng)需要一個新的編程模型?

Actor模型作為一種高性能網(wǎng)絡(luò)中的并行處理方式由Carl Hewitt幾十年前提出-高性能網(wǎng)絡(luò)環(huán)境在當時還不可用。如今,硬件和基礎(chǔ)設(shè)施的能力已經(jīng)趕上并超越了Hewitt的愿景。因此,高要求的分布式系統(tǒng)的建造者遇到了不能完全由傳統(tǒng)的面向?qū)ο缶幊?OOP)模型解決的挑戰(zhàn),但這可以從Actor模型中獲益。
今天,Actor模型不僅被認為是高效的解決方案——這已經(jīng)被世界上要求最高的應(yīng)用所檢驗。為了突出Actor模型解決的問題,這個主題討論以下傳統(tǒng)編程的假設(shè)與現(xiàn)代多線程、多CPU體系架構(gòu)之間的不匹配:

  • 封裝的挑戰(zhàn)
  • 現(xiàn)代計算機體系結(jié)構(gòu)中共享內(nèi)存的錯覺
  • 一個調(diào)用棧的錯覺

封裝的挑戰(zhàn)

OOP的一個核心支柱是封裝。封裝表明一個對象的內(nèi)部狀態(tài)不能直接從外部訪問;它只可以通過調(diào)用一組輔助的方法修改。對象負責(zé)暴露保護它所封裝數(shù)據(jù)的不變性的安全操作。例如,在一個有序二叉樹上的操作不允許違反樹的有序性。調(diào)用者希望保持有序性,當查詢樹上一條特定的數(shù)據(jù)時,它們需要能夠依賴這個約束。
當分析OOP運行時的行為時,我們有時候畫出一個消息序列圖展示方法調(diào)用的交互過程。例如:

不幸的是,上面的圖表沒能精確表示執(zhí)行過程中對象的生命線。實際上,一個線程執(zhí)行所有的調(diào)用,所有對象的不變體約束出現(xiàn)在同一個方法被調(diào)用的線程中。更新線程執(zhí)行圖,它看起來是這樣:

當試圖對多線程行為建模時,上面闡述的重要性變得明顯了。突然,我們畫出的簡潔的圖表變得不夠充分了。我們可以嘗試解釋多線程訪問同一對象:

有一個執(zhí)行部分,兩個線程調(diào)用同一個方法。不幸的是,對象的封裝模型不能保證執(zhí)行這部分時會發(fā)生什么。兩個線程之間沒有某種協(xié)調(diào)的話,兩個調(diào)用指令將以不能保證不變體性質(zhì)的任意方式相互交錯。現(xiàn)在,想象一下這個由多個線程存在而變得復(fù)雜的問題。

解決這個問題的常見方法是給這些方法加一個鎖。盡管這保證了在給定的時間內(nèi)最多一個線程將執(zhí)行該方法,但是這是一個代價高昂的策略: 

  • 鎖嚴重限制了并發(fā),鎖在現(xiàn)代CPU體系結(jié)構(gòu)中的代價很高,要求操作系統(tǒng)承擔掛起線程并隨后恢復(fù)它的重負。
  • 調(diào)用者線程被阻塞,因此它不能做其他有意義的工作。在桌面應(yīng)用中這是不能接受的,我們希望使應(yīng)用程序的用戶界面(UI)即使在一個很長的后臺作業(yè)正在運行的時候也是可響應(yīng)的。在后臺,阻塞是完全浪費的。或許有人想到這可以通過開啟一個新線程彌補,但線程也是一個代價高昂的抽象。
  • 鎖引入了一個新的威脅:死鎖

這些事實導(dǎo)致一個無法取勝的局面:

  • 沒有足夠的鎖,狀態(tài)會被破壞
  • 有足夠的鎖,性能受損并很容易導(dǎo)致死鎖

另外,鎖只有在本地有用。當涉及跨機器協(xié)調(diào)時,唯一可選的是分布式鎖。不幸的是,分布式鎖比本地鎖低效幾個數(shù)量級,并且限制了伸縮性。分布式鎖協(xié)議需要在網(wǎng)絡(luò)中跨機器的多輪通信,因此延遲飛漲。

在面向?qū)ο笳Z言中,我們通常很少考慮線路或線性執(zhí)行路徑。我們經(jīng)常把系統(tǒng)想象成一個對象實例的網(wǎng)絡(luò),這些實例對象響應(yīng)方法調(diào)用、修改自身內(nèi)部狀態(tài)、然后通過方法調(diào)用相互通信以驅(qū)動整個應(yīng)用狀態(tài)向前:

然而,在一個多線程的分布式環(huán)境中,實際發(fā)生的是線程沿著方法調(diào)用貫穿這個對象實例網(wǎng)絡(luò)。因此,線程是真正的運行驅(qū)動者:

【總結(jié)】

  • 對象只能在單線程訪問時保證封裝(不變體的保護),多線程執(zhí)行幾乎總會導(dǎo)致破壞對象內(nèi)部狀態(tài)。每個不變體可以被處于同一代碼段相互競爭的兩個線程違反。
  • 雖然鎖似乎是對維護多線程時的封裝很自然的補救,實際上,在任何現(xiàn)實應(yīng)用中鎖很低效并很容易導(dǎo)致死鎖。
  • 鎖在本地有用,但試圖使鎖成為分布式的,可以提供有限潛力的擴展。

現(xiàn)代計算機體系結(jié)構(gòu)中共享內(nèi)存的錯覺

80-90年代的編程模型定義:寫入一個變量意味著直接寫到內(nèi)存位置 (這在一定程上混淆了局部變量可能僅存在于寄存器)。在現(xiàn)代體系架構(gòu)中,如果我們簡化一下,CPUs會寫到cache行而不是直接寫入內(nèi)存。大多數(shù)caches是CPU局部私有的,也就是,一個核寫入變量不會被其他核看到。為了使局部改變對其他核可見,因此對于另一個線程,cache行需要被傳送到其他核的cache。

在JVM中,我們必須通過使用volatile或Atomic顯式地指示線程間共享的內(nèi)存位置。否則,我們只能在鎖定的部分訪問這些內(nèi)存。為什么我們不將所有變量標記為volatile?因為跨核傳送cache行是一個代價非常高昂的操作!這樣做會隱式地停止涉及做額外工作的核,并導(dǎo)致緩存一致性協(xié)議的瓶頸。(CPUs用于主存和其他CPUs之間傳輸cache行的協(xié)議)。結(jié)果便是降低數(shù)量級的運行速度。

即使對于了解這個情況的開發(fā)者,搞清楚哪個內(nèi)存位置應(yīng)該被標記為volatile或者使用哪一種原子結(jié)構(gòu)是一門黑暗的藝術(shù)。

【總結(jié)】

  • 沒有真正的共享內(nèi)存了,CPU核就像網(wǎng)絡(luò)中的計算機一樣,將數(shù)據(jù)塊(cache行)顯式地傳送給彼此。CPU之間的通信和網(wǎng)絡(luò)中計算機之間通信的相同之處比許多人意識到的要多。傳送消息是如今跨CPUs或網(wǎng)絡(luò)中計算機的標準。
  • 相對于通過標記為共享或使用原子數(shù)據(jù)結(jié)構(gòu)的變量來隱藏消息傳遞的層面,一個更規(guī)范和有原則的方法是保存狀態(tài)到一個并發(fā)實體本地并通過消息顯式地在并發(fā)實體間傳送數(shù)據(jù)或事件。

一個調(diào)用棧的錯覺

今天,我們常常將調(diào)用棧視為理所當然。但是,調(diào)用棧是在一個并發(fā)程序不那么重要的時代發(fā)明的,因為多CPU系統(tǒng)那時不常見。調(diào)用棧沒有跨越線程,因而沒有對異步調(diào)用鏈建模。

當一個線程意圖委派一個任務(wù)給后臺的時候會出現(xiàn)問題。實際上,這意味著委托給另一個線程。這不是一個簡單的方法、函數(shù)調(diào)用,因為調(diào)用嚴格上屬于線程內(nèi)部。通常,調(diào)用者(caller)線程將一個對象放入與一個工作線程(callee)共享的內(nèi)存位置,反過來,這個工作線程(callee)在某個循環(huán)事件中獲取這個對象。這使得調(diào)用者(caller)線程可以向前運行和執(zhí)行其他任務(wù)。
第一個問題是:調(diào)用者(caller)線程如何被通知任務(wù)完成了?但是當一個任務(wù)失敗且?guī)в挟惓5臅r候一個更嚴重問題出現(xiàn)了。異常應(yīng)該傳播到哪里?異常將被傳播到工作者(worker)線程的異常處理器而完全忽略誰是真正的調(diào)用者(caller):

這是一個嚴重的問題。工作者(worker)線程如何處理這種情況?它可能無法解決這個問題,因為它通常不知道失敗任務(wù)的目的。調(diào)用者(caller)線程需要以某種方式被通知,但是沒有調(diào)用棧去返回一個異常。失敗通知只能通過邊信道完成,例如,將一個錯誤代碼放在調(diào)用者(caller)線程原本期待結(jié)果準備好的地方。如果這個通知不到位,調(diào)用者(caller)線程不會被通知任務(wù)失敗和丟失!這和網(wǎng)絡(luò)系統(tǒng)的工作方式驚人地相似-網(wǎng)絡(luò)系統(tǒng)中的消息和請求可以丟失或失敗而沒有任何通知。
在任務(wù)出錯和一個工作者(worker)線程遇到一個bug并不可恢復(fù)的時候,這個糟糕的情況會變得更糟。例如,一個由bug引起的內(nèi)部異常向上傳遞到工作者(worker)線程的根部并使該線程關(guān)閉。這立即產(chǎn)生一個疑問,誰應(yīng)該重啟由該線程持有的這一服務(wù)的正常操作,以及怎樣將它恢復(fù)到一個已知的良好狀態(tài)?乍一看,這似乎很容易,但是我們突然遇到一個新的、意外的現(xiàn)象:線程正在執(zhí)行的實際任務(wù)已經(jīng)不在任務(wù)被取走得共享內(nèi)存位置了 (通常是一個隊列)。事實上,由于異常到達頂部,展開所有的調(diào)用棧,任務(wù)狀態(tài)完全丟失了!我們已經(jīng)丟失了一條消息,盡管這是本地的通信,沒有涉及到網(wǎng)絡(luò) (消息丟失是可期望的)。

【總結(jié)】

為了在當下系統(tǒng)實現(xiàn)有意義的并發(fā)和性能,線程必須以一種高效的、無阻塞的方式相互委派任務(wù)。有了這種任務(wù)委派并發(fā)方式(網(wǎng)絡(luò)/分布式計算更是如此),基于棧調(diào)用的error處理失效了,新的、顯式的error信號機制需要被引入。失敗成為領(lǐng)域模型的一部分。任務(wù)委派的并發(fā)系統(tǒng)需要處理服務(wù)故障并且有原則性的方法恢復(fù)它們。這種服務(wù)的客戶端需要知道任務(wù)/消息會在重啟中丟失。即使不丟失,一個響應(yīng)或許會由于隊列 (一個很長的隊列) 中先前的任務(wù)而發(fā)生任意的延遲,由垃圾回收造成的延遲等等。在這些情況下,并發(fā)系統(tǒng)應(yīng)該以超時的形式對待響應(yīng)截止時間,就像網(wǎng)絡(luò)/分布式系統(tǒng)一樣。

以上就是詳解為什么現(xiàn)代系統(tǒng)需要一個新的編程模型的詳細內(nèi)容,更多關(guān)于現(xiàn)代系統(tǒng)需要一個新的編程模型的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談架構(gòu)模式變遷之從分層架構(gòu)到微服務(wù)架構(gòu)

    淺談架構(gòu)模式變遷之從分層架構(gòu)到微服務(wù)架構(gòu)

    一般地,架構(gòu)模式大致可以分成兩類,單體架構(gòu)(monolithic architecture)和分布式架構(gòu)(distributed architecture)。
    2021-05-05
  • Sqoop的安裝與使用詳細教程

    Sqoop的安裝與使用詳細教程

    Sqoop是一款開源的工具,主要用于在Hadoop與傳統(tǒng)數(shù)據(jù)庫間進行數(shù)據(jù)的傳遞,這篇文章主要介紹了Sqoop的安裝與使用詳細教程,需要的朋友可以參考下
    2021-04-04
  • chrome開發(fā)者助手插件v2.10發(fā)布提升開發(fā)效率不再只是口號

    chrome開發(fā)者助手插件v2.10發(fā)布提升開發(fā)效率不再只是口號

    這篇文章主要介紹了chrome開發(fā)者助手插件v2.10發(fā)布提升開發(fā)效率不再只是口號,這個版本重點提升了常用工具的使用效率,需要的朋友可以參考下
    2021-03-03
  • HTTP中ETag語法及使用實戰(zhàn)詳解

    HTTP中ETag語法及使用實戰(zhàn)詳解

    這篇文章主要為大家介紹了HTTP中ETag語法及使用實戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Pascal Move的用法

    Pascal Move的用法

    這篇文章主要介紹了Pascal Move的用法,需要的朋友可以參考下
    2021-11-11
  • Scala函數(shù)式編程專題--函數(shù)思想介紹

    Scala函數(shù)式編程專題--函數(shù)思想介紹

    這篇文章主要介紹了Scala函數(shù)式編程的的相關(guān)資料,文中講解非常細致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 一文讀懂modbus slave和modbus poll使用說明

    一文讀懂modbus slave和modbus poll使用說明

    modbus poll和modbus slave是一款實用的modbus開發(fā)和調(diào)試工具,可以非常方便的進行modbus調(diào)試,是非常有用的Modbus主機/從機模擬程序,這篇文章給大家介紹modbus slave和modbus poll使用說明,感興趣的朋友一起看看吧
    2021-04-04
  • 解讀Serverless架構(gòu)的前世今生

    解讀Serverless架構(gòu)的前世今生

    云計算的不斷發(fā)展,涌現(xiàn)出很多改變傳統(tǒng)IT架構(gòu)和運維方式的新技術(shù),而以虛擬機、容器、微服務(wù)為代表的技術(shù)更是在各個層面不斷提升云服務(wù)的技術(shù)能力,它們將應(yīng)用和環(huán)境中很多通用能力變成了一種服務(wù)。但無論這些技術(shù)應(yīng)用在哪里,幫助企業(yè)降本增效是技術(shù)變革永恒的主題。
    2021-05-05
  • 淺談測試驅(qū)動開發(fā)TDD之爭

    淺談測試驅(qū)動開發(fā)TDD之爭

    在軟件行業(yè)中,神仙打架的名場面,那就不得不提的是2014年的那場——測試驅(qū)動開發(fā)(TDD)之爭。
    2021-05-05
  • 詳解Python OpenCV數(shù)字識別案例

    詳解Python OpenCV數(shù)字識別案例

    信用卡識別的案例用到了圖像處理的一些基本操作,對剛上手CV的人來說還是比較友好的。
    2021-05-05

最新評論