語言表達(dá)了我們的思維方式。我們?nèi)绾翁幚韱栴}并制定解決方案取決于我們可以使用語言表達(dá)的概念。這對于編程語言也是如此。給定一個問題,為解決該問題而編寫的程序可能因?yàn)檎Z言的不同而有較大的差異。本書講述的是如何用Go語言來表達(dá)并發(fā)算法并編寫程序,以及如何了解這些程序的行為方式。
Go語言與許多流行語言的不同之處在于它強(qiáng)調(diào)可理解性。這與可讀性不同。許多用易于閱讀的語言編寫的程序是難以理解的。過去,我也曾陷入使用使編程變得容易的框架來編寫組織良好的程序的陷阱。這種方法的問題在于,一旦編寫完成,程序就開始了自己的生命周期,而其他人則接管了它的維護(hù)工作。在開發(fā)階段形成的專有知識丟失了,如果沒有原始開發(fā)團(tuán)隊(duì)中最后一個人的幫助,那么團(tuán)隊(duì)留下的程序?qū)o法理解。開發(fā)程序與寫小說沒有太大區(qū)別。小說是為了讓別人讀而寫的,程序也是如此。你的程序如果沒有人能理解,那么肯定無法長期運(yùn)行。
本書將嘗試解釋如何在Go語言中使用并發(fā)結(jié)構(gòu)進(jìn)行思考,以便你在獲得一段代碼時能夠清晰地理解該程序?qū)⑷绾芜\(yùn)行,并且其他人也可以更輕松地理解你編寫的程序。本書首先對并發(fā)以及Go語言的處理方式進(jìn)行較高層次上的闡釋,然后使用并發(fā)算法解決若干個實(shí)用的數(shù)據(jù)處理問題。畢竟,編寫程序就是為了處理數(shù)據(jù)。本書希望你理解并發(fā)模式是如何在解決現(xiàn)實(shí)問題的同時全面發(fā)展的,這可以幫助你獲得高效使用該語言的技能。本書后面的章節(jié)還介紹更多示例,這些示例涉及計(jì)時、周期性任務(wù)、服務(wù)器編程、流媒體和原子內(nèi)存操作等。最后一章則討論故障排除和調(diào)試等。
限于篇幅,本書無法討論與并發(fā)相關(guān)的所有主題。還有很多領(lǐng)域沒有被探索。但是我相信,你一旦完成了本書中提供的所有示例,就會對使用并發(fā)解決問題更有信心。每個人都在抱怨并發(fā)很難,但是,正確使用語言將使開發(fā)人員可以更輕松地生成正確的程序。你應(yīng)該永遠(yuǎn)記住的經(jīng)驗(yàn)法則是:正確性優(yōu)先于性能。因此,我們首先要讓它正常工作,然后才能讓它更快地工作。
本書讀者
如果你是一名具有Go語言基礎(chǔ)知識并希望獲得高并發(fā)后端應(yīng)用程序開發(fā)專業(yè)知識的開發(fā)人員,那么這本書就是適合你的。本書還將吸引各種經(jīng)驗(yàn)水平的Go開發(fā)人員,讓他們的后端系統(tǒng)更加健壯和可擴(kuò)展。
內(nèi)容介紹
本書共分10章,各章內(nèi)容如下。
第1章并發(fā)高級概述,詳細(xì)闡述并發(fā)是什么以及不是什么,特別是它與并行的關(guān)系。本章還介紹共享內(nèi)存和消息傳遞范式,以及常見的并發(fā)概念,如競爭、原子性、死鎖和饑餓等。
第2章Go并發(fā)原語,介紹用于并發(fā)編程的Go語言原語,包括goroutine、通道、互斥體、等待組和條件變量等。
第3章Go內(nèi)存模型,詳細(xì)探討內(nèi)存操作的可見性保證,介紹happened-before關(guān)系,這允許你推理并發(fā)行為。本章還討論并發(fā)原語和一些標(biāo)準(zhǔn)庫函數(shù)的內(nèi)存可見性保證。
第4章一些眾所周知的并發(fā)問題,研究著名的生產(chǎn)者/消費(fèi)者問題、哲學(xué)家就餐問題和速率限制算法。
第5章工作池和管道,詳細(xì)介紹工作池的機(jī)制,這是在有限并發(fā)下處理大量數(shù)據(jù)的常用方法。本章還演示多種并發(fā)數(shù)據(jù)管道實(shí)現(xiàn),以幫助你編寫高效的數(shù)據(jù)處理應(yīng)用程序。
第6章錯誤和恐慌處理,深入探討如何處理并發(fā)程序中的錯誤和恐慌,以及如何傳遞錯誤。
第7章Timer和Ticker,介紹一次性定時器Timer和周期性定時器Ticker。 Timer用于稍后運(yùn)行一些東西,而Ticker則可用于定期運(yùn)行一些東西。
第8章并發(fā)處理請求,主要討論服務(wù)器編程。本章討論的許多概念涉及處理多種請求,因此它們可以廣泛應(yīng)用于各種場景。本章描述如何有效地使用上下文、如何分配工作和收集結(jié)果、如何限制并發(fā)以及如何流傳輸數(shù)據(jù)。
第9章原子內(nèi)存操作,詳細(xì)闡釋原子內(nèi)存操作和它們的內(nèi)存保證,并演示原子的一些實(shí)際用途。
第10章解決并發(fā)問題,討論讀取堆棧跟蹤信息這一被低估但必不可少的技能,以及如何在運(yùn)行時檢測故障并修復(fù)它們。
充分利用本書
你需要對Go語言以及適合你的操作系統(tǒng)運(yùn)行的Go開發(fā)環(huán)境有基本的了解。本書不依賴任何第三方工具或庫,你只需使用你最熟悉的代碼編輯器即可。所有示例和代碼示例都可以使用Go構(gòu)建系統(tǒng)進(jìn)行構(gòu)建和運(yùn)行。
下載示例代碼文件
本書的代碼包已經(jīng)托管在GitHub上,其網(wǎng)址如下:
https://github.com/PacktPublishing/Effective-Concurrency-in-Go
代碼如果有更新,則會在現(xiàn)有GitHub存儲庫上被更新。
下載彩色圖像
我們還提供了一個PDF文件,其中包含本書中使用的屏幕截圖/圖表的彩色圖像。你可以訪問以下網(wǎng)址下載該文件:
https://packt.link/3rxJ9
本書約定
本書中使用了許多文本約定。
(1)代碼格式文本:表示文本中的代碼字、數(shù)據(jù)庫表名、文件夾名、文件名、文件擴(kuò)展名、路徑名、虛擬URL、用戶輸入和Twitter句柄等。以下段落就是一個示例:
本章源代碼可在本書配套的GitHub存儲庫中找到,其網(wǎng)址如下:
https://github.com/PacktPublishing/Effective-Concurrency-in-Go/tree/main/chapter4
(2)有關(guān)代碼塊的設(shè)置如下所示:
1: chn := make(chan bool) // 創(chuàng)建一個無緩沖通道
2: go func() {
3: chn <- true // 發(fā)送到通道
4: }()
5: go func() {
6: var y bool
7: y <-chn // 從通道接收
8: fmt.Println(y)
9: }()
(3)任何命令行輸入或輸出都是采用如下形式編寫的:
{"row":65,"height":172.72,"weight":97.61}
{"row":64,"height":195.58,"weight":81.266}
{"row":66,"height":142.24,"weight":101.242}
{"row":68,"height":152.4,"weight":80.358}
{"row":67,"height":162.56,"weight":104.87400000000001}
(4)術(shù)語或重要單詞采用中英文對照形式給出,括號內(nèi)保留其英文原文,方便讀者進(jìn)行對照和查看。示例如下:
多年來,人們已經(jīng)開發(fā)出了若干種數(shù)學(xué)模型來分析和驗(yàn)證并發(fā)系統(tǒng)的行為。通信順序進(jìn)程(communicating sequential processes,CSP)就是影響Go語言設(shè)計(jì)的模型之一。在CSP中,系統(tǒng)由多個并行運(yùn)行的順序進(jìn)程組成。
(5)本書還使用了以下兩個圖標(biāo)。
表示警告或重要的注意事項(xiàng)。
表示提示信息或操作技巧。