Go 語言併發程式設計(一):併發的演化歷史
根據2018年09月16日武漢·光谷貓友會,武漢的Gopher小夥伴分享的Go併發程式設計整理的內容。本次分享的主題內容包含Go語言併發哲學,併發的演化歷史,你好併發,併發的記憶體模型,常見的併發模式等內容。關於併發程式設計的補充內容可以參考《Go語言高階程式設計》第一章的相關內容。
本次整理併發的演化歷史部分的內容。
Go語言併發哲學
Do not communicate by sharing memory, instead, share memory by communicating!
不要通過共享記憶體來通訊, 而是通過通訊來共享記憶體!
不要逆行!
併發的演化歷史
Go語言最早從UNIX系統的B語言和C語言演化而來,其中的併發特性是從Newsqueak、Alef和Limbo等語言演化而來。其中Newsqueak是Go之父Rob Pike於989年設計的語言,Alef則是Phil Winterbottom於1993年對C語言擴充套件了併發特性的語言,Limbo也是Rob Pike參與設計的支援併發的語言。由此可見,Rob Pike在併發程式語言領域已經積累了幾十年的設計經驗,Go語言正是站在這些前輩的基礎上涅槃重生的。
Go語言併發的理論基礎是來自Hoare於1978年發表的CSP論文(Hoare就是發明快速排序的大牛)。更通俗的類比,CSP對應的程式設計模型和UNIX中的管道非常相似,而管道更是在1964年就已經發明瞭。因此,從理論上看,Go語言的併發並非什麼新發明的特性,它只不過是將CSP代表的通過訊息同步的程式設計模型帶入了工業開發領域。
Newsqueak素數篩 - Rob Pike, 1989
先看看素數篩的原理圖:
然後是Newsqueak素數篩程式碼:
<code>counter := prog(c:chan of int) { i:=2; for(;;) c <-= i++; }; filter := prog(prime:int, listen, send:chan of int) { i:int; for(;;) if((i = <-listen)%prime) send <-= i; }; sieve := prog() of chan of int { c := mk(chan of int); begin counter(c); prime := mk(chan of int); begin prog(){ p:int; newc:chan of int; for(;;){ prime <-= p =<- c; newc = mk(); begin filter(p, c, newc); c = newc; } }(); become prime; }; prime:=sieve();</code>
其中begin關鍵字啟動一個併發,類似Go語言的go關鍵字。而become關鍵字表示返回值,類似return語句。因此說Newsqueak和Go語言的併發有很多相似之處。
Alef - Phil Winterbottom, 1993
然後是Alef語言。據說這個語言是C語言之父Ritchie所鍾愛的語言。不過Alef只是短暫地出現在Plan9系統中。目前傳世的官方文件只有入門指南和參考手冊。
下面的程式碼是Alef文件中摘取的片段:
<code>#include <alef.h> void receive(chan(byte*) c) { byte *s; s = <- c; print("%s\n", s); terminate(nil); } void main(void) { chan(byte*) c; alloc c; proc receive(c); task receive(c); c <- = "hello proc or task"; c <- = "hello proc or task"; print("done\n"); terminate(nil); }</code>
可以將Alef看作是類似C++的語言,基礎的語法完善和C語言儲存一致,但是在併發程式設計方向做了擴充套件。其中proc是啟動一個程序,task是啟動一個執行緒。
因為C語言沒有GC特性,因此Alef併發所建立或分享的資源管理將會是一個極大的調整。併發的語法雖然看著很美,但是進行真正的併發程式設計可能沒有那麼容易。
Alef產生的併發體可能異常複雜,下圖是Alef文件中摘取的圖片:
總共有6個執行緒分佈在3個程序中,現場併發體相互之間通過管道進行通訊。因為Alef同時支援程序和執行緒,可以說它其實是偽裝成程式語言的作業系統!
其它內容待續
線上瀏覽幻燈片:
https://talks.godoc.org/github.com/chai2010/awesome-go-zh/chai2010/chai2010-golang-concurrency.slide
幻燈片原始檔:
https://github.com/chai2010/awesome-go-zh/tree/master/chai2010