1. 程式人生 > >Erlang併發程式設計-簡介概要

Erlang併發程式設計-簡介概要

簡介

Erlang是一門被設計用於編寫併發、實時、分散式系統的新語言。

很多年來,併發實時系統的程式設計技術一直落後於序列應用的程式設計。當使用C或Pascal進行序列程式設計已經成為實踐標準時,大多數實時系統的程式設計師還在倒騰著彙編。如今的實時系統可以使用Ada、Modula2、Occam等為併發程式設計提供了顯式支援的語言來編寫,或是仍舊使用C這樣缺乏併發結構的語言。

我們對併發的興趣源自於對一些展現出大規模併發的問題的研究。這是實時控制系統的一個典型屬性。Erlang程式設計師可以顯式指定哪些活動需要由併發程序來展現。這種觀念與Occam、CSP、Concurrent Pascal等語言類似,但與那些並不為了對現實世界的併發進行建模而引入併發的語言不同,這些語言引入併發的目的只是為了將編譯出可在並行處理器上執行的程式以獲得更高的效能。

現今Prolog和ML等語言已經被大範圍用於工業應用之中,並極大地降低了設計、實現和維護應用的成本。我們對Erlang的設計和實現也是為了將併發實時系統程式設計提高到一個相似的高度。

申明式語法

    Erlang具備申明式的語法,且大部分都無副作用。

併發

    Erlang具備一個使用訊息傳遞的基於程序的併發模型。Erlang的併發機制是輕量級的,如程序只佔用極少的記憶體,程序的建立、刪除以及訊息傳遞也都只涉及極少量的計算。

實時

    Erlang可用於對相應延遲在毫秒數量級的軟實時系統進行程式設計。

持續運作

    Erlang具備替換執行時系統程式碼的原語,並允許新舊版本的程式碼同時執行。這在電話交換機、空中交通控制等“不停機”系統中有極大的用處,這些系統在軟體變更時都不能停機。

健壯

    在上述系統中,安全性是一個關鍵需求。Erlang具備三種結構來檢測執行時錯誤。這些可用於編寫健壯的系統。

記憶體管理

    Erlang是一門具備實時垃圾回收機制的符號計算語言。記憶體在需要時自動分配,在不需要時自動回收。典型的記憶體管理相關的程式設計錯誤都不再存在。

分散式

    Erlang沒有記憶體共享。所有程序間互動都通過非同步訊息傳遞完成。使用Erlang可以輕易地構建分散式系統。為單處理器編寫的應用不花什麼力氣就可以移植到處理器網路上執行。

整合

    Erlang可以簡單地呼叫其他語言編寫的程式。通過Erlang的介面系統,這些程式對於程式設計師來看就好像是用Erlang編寫的一樣。

我們從申明式語言和併發語言中借鑑了大量思想。早期Erlang的語法多半歸功於STRAND,儘管當前的語法讓人覺得像是無型別的ML。其併發模型則與SDL類似。

我們的目標是為健壯的大規模併發工業應用程式設計提供一種精煉、簡單和高效的語言。因此,出於效率原因,我們放棄了許多現代函式式語言中的特性。Currying、高階函式、延遲求值、ZF comprehension、邏輯變數、deep guards等,增強了申明式程式語言的表達能力,但對於工業控制應用而言,沒有這些特性也不會有什麼顯著影響。倒是模式匹配語法的使用和Erlang變數的“單次賦值”屬性,使得我們能夠編寫清晰、短小且可靠的程式。

最初Erlang是邊實現邊設計的,第一個版本是一個使用Prolog編寫的直譯器。與此同時,我們非常幸運地擁有了第一批熱情的使用者群,他們當時正在開發一個新電話交換機的原型。

這便催生了一條極為有效的語言設計途徑。不被使用的構件被拋棄,對於令我們的使用者不得不編寫令人費解的程式碼的問題,則引入新的語言構件予以解決。儘管我們經常會對語言進行一些不向下相容的更改,我們的使用者還是飛速地編寫了成千上萬行的程式碼,並積極地鼓動其他人來使用這門語言。他們的努力催生了一種新的電話交換機程式設計方法,相關的一些內容被髮表在[??]和[??]。

第一版基於Prolog的Erlang直譯器很早以前就被編譯型的實現所替代了。其中的一個實現可以免費獲取,並使用非商業許可證。當前的Erlang實現在兼顧速度和輕量級併發的同時滿足了我們的實時性要求。Erlang實現已經被移植到多種作業系統及多種處理器上。

Erlang適用於對很大範圍內的併發應用進行程式設計。不少工具被開發出來用於輔助Erlang程式設計,如X Window System的介面、ASN.1編譯器(使用Erlang編寫並生成Erlang程式碼)、分析程式生成器、偵錯程式……

讀者群

本書面向對實時控制系統感興趣且有一定的程式設計經驗的人。但並不需要對函式式或邏輯語言有所瞭解。

本書中的材料與近年來在Ericsson及其全世界範圍內的子公司以及瑞士大學舉辦的多次Erlang課程有關。該課程為期四天,不光展示語言本身,也對Erlang的多種程式設計正規化進行介紹。課程的最後一天通常是一個程式設計練習,學生們將編寫一個與第??章所描述的類似的電話交換機控制系統,並在一臺實際的交換機上執行!

概要

本書被劃分為兩大部分。第一部分“程式設計”,介紹Erlang語言以及在Erlang程式設計中常見的一些程式設計正規化。第二部分,“應用”,由一系列完備的章節構成,包含典型Erlang應用的案例分析。

程式設計

第1章是對Erlang的一個介紹性教程。通過一系列示例對語言的一些主要思想予以說明。

第2章介紹序列程式設計。這裡將會介紹模組系統,這會是我們談及Erlang時的一個基本術語。

第3和第4章包含一系列使用列表和元組進行程式設計的示例。這裡將介紹列表和元組的基本程式設計技巧。在後續章節中需要用到的一些標準模組在此也會提及。其中包括實現集合、字典、平衡及非平衡二叉樹等等的模組。

第5章介紹併發。在序列程式設計基礎之上新增少量的原語便將Erlang變為一門併發程式語言。我們將介紹用於建立並行程序以及在程序間進行訊息傳遞的原語。我們還將介紹為了將程序與一個名稱相關聯而引入的程序註冊機制。

此處將解釋伺服器—客戶端模型背後的基本思想。該模型在後續章節中被大量使用,同時也是用於協調多個並行程序間的活動的一種基本程式設計技術。我們還將介紹可讓我們編寫實時程式的超時。

第6章是對分散式程式設計的一個概述,解釋了編寫分散式應用的一些動機。我們描述了用於編寫分散式Erlang程式的語言原語並解釋瞭如何在Erlang節點網路中排布多組程序。

第7章解釋了Erlang中的錯誤處理機制。我們將Erlang設計用於編寫健壯的應用,語言中包含了三種正交的機制用於完成錯誤檢查。我們認為語言應該在執行時檢測出儘可能多的錯誤並讓程式設計師負責糾正這些錯誤。

第8章展示瞭如何使用前一章介紹的錯誤處理原語來構建健壯的容錯系統。我們展示瞭如何將錯誤的程式碼拒之門外,提供了一個容錯的伺服器(通過擴充套件客戶端伺服器模型)並展示瞭如何對計算進行“隔離”以便在出錯時對破壞範圍進行限制。

第9章包含了一系列在本書其他部分未提及的程式設計思想和技巧。我們在此討論尾遞迴優化。對於希望正確編寫出不間斷執行程式的程式設計師而言,對該優化的理解是至關重要的。We then introduce references which provide unique unforgetable symbols. 本章之後的兩節描述瞭如何更改執行時系統的Erlang程式碼的細節(編寫不停機系統需要使用這種技術)以及如何將Erlang與使用其他語言編寫的程式對接。之後,我們將介紹用於高效處理大量無型別資料的二進位制資料處理、為每個程序提供了可銷燬儲存能力的程序字典,以及作為分散式Erlang核心的網路核心。最後我們將對執行效率進行討論,並舉例說明如何編寫高效的Erlang程式碼。
應用

第10章展示瞭如何使用Erlang編寫一個數據庫。我們從第??章開發的簡單字典模組和第??章的客戶端—伺服器模型開始,由此完成一個簡單的併發資料庫。然後我們將展示如何以組織成多級樹形結構的並行程序來實現該資料庫,以此改善其吞吐量。接著我們加入事務性,以使得多個序列資料庫操作可以表現出原子性。

在這之後,我們為資料庫增加“回滾”機制以允許我們“撤銷”先前的資料庫操作。回滾示例對非破壞性賦值進行了漂亮的展示。

接著我們討論如何讓我們的資料庫能夠容錯。最後,我們展示如何將一個外部資料庫與我們的資料庫整合,併為程式設計師提供統一的介面。

第11章介紹分散式程式設計技術。我們展示如何使用Erlang實現多種常見的分散式程式設計技術,如遠端過程呼叫、廣播、promises等等。

第12章研究分散式資料問題。許多情況下,執行在不同物理機器上的多個應用希望共享一些公共資料結構。本章描述用於實現分散式系統中的共享資料的各種技術。

第13章是對Erlang作業系統的討論。由於所有的程序管理都在Erlang內部完成,我們對傳統作業系統提供的服務所需甚少。我們在此展現Erlang作業系統中用於完成語言標準分散式任務的主要元件。該作業系統可以作為更專一化的作業系統的基礎以用於某個具體應用之中。

第14章與兩個實時控制問題相關。第一個是著名的電梯控制問題——這裡我們將看到將系統建模為一組並行程序提供了一套簡單優雅的解決方案。第二部分討論“程序控制”,此處我們的“程序”是一個衛星。觀測衛星的唯一途徑是分析安裝在衛星上的感測器所傳送的資料。變更衛星行為的唯一途徑是向衛星上的儀器傳送指令。儘管這裡以衛星控制系統為例,相關技術可以應用於更廣泛的範圍。

第15章是一個小型本地電話交換機的實時控制系統例項。Erlang是Ericsson電腦科學實驗室開發出來的,而Ericsson也是世界上主要電話交換機的生產商之一——簡化電信程式設計始終都是我們的主要興趣所在!

本章中的示例只是一個“玩具”系統。然而麻雀雖小五臟俱全,它展示了用Erlang構建電信軟體的許多技術。該示例只是那些用於控制複雜電信應用的龐大Erlang程式的小兄弟。這些程式都由數萬行Erlang程式碼構成,是本章所描述的各種程式設計技術的擴充套件應用。

本章的末尾對SDL做了一個簡短的介紹(SDL被廣泛用於描述電信系統的行為)——我們在此展現了一份SDL規範與實現這份規範的Erlang程式碼的一一對應關係。SDL與Erlang之間的概念“鴻溝”很小——這將降低實時系統的設計實現成本。

第16章簡短地介紹了ASN.1並給出了一個從ASN.1到Erlang的交叉編譯器。ASN.1是用於描述通訊協議資料格式的標準。本章展現了ASN.1規範與用於操作ASN.1描述的資料包的Erlang程式碼間的相似性。為系統中通訊軟體部分自動產生大部分程式碼的能力大大簡化了系統的構建過程。

第17章展示瞭如何為Erlang應用構建使用者介面。本章展示了兩點:第一,併發程序組如何良好地對映到視窗系統中的一組物件;第二,讓Erlang與其他語言編寫軟體包協同運作。

第18章中我們討論面向物件程式語言的一些主要屬性以及如何在Erlang中予以實現。我們將討論面向物件設計及其Erlang實現之間的關係。