Go語言透過編譯器執行時(runtime),從語言上支援了並發的特性;並發是透過goroutine完成。 goroutine是一種非常輕量級的實現,可在單一進程中執行成千上萬的並發任務,它是Go語言並發設計的核心。使用go關鍵字就可以創建goroutine,將go聲明放到一個需調用的函數之前,在相同地址空間調用運行這個函數,這樣該函數執行時便會作為一個獨立的並發線程。
本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。
並髮指在同一時間內可以執行多個任務。並發程式設計意義較廣泛,包含多執行緒程式設計、多進程程式設計及分散式程式等。
Go 語言透過編譯器執行時間(runtime),從語言上支援了並發的特性。 Go 語言的並發透過 goroutine 特性完成。 goroutine 類似於線程,但是可以根據需要建立多個 goroutine 並發工作。 goroutine 是由 Go 語言的運行時調度完成,而執行緒則由作業系統調度完成。
Go 語言也提供 channel 在多個 goroutine 間溝通。 goroutine 和 channel 是 Go 語言秉持的 CSP(Communicating Sequential Process)並發模式的重要實作基礎。
Goroutine 介紹
goroutine 是一種非常輕量級的實現,可在單一進程中執行成千上萬的並發任務,它是Go語言並發設計的核心。
說到底 goroutine 其實就是線程,但是它比線程更小,十幾個 goroutine 可能體現在底層就是五六個線程,而且Go語言內部也實現了 goroutine 之間的記憶體共享。
使用go 關鍵字就可以創建goroutine,將go 聲明放到一個需調用的函數之前,在相同地址空間調用運行這個函數,這樣該函數執行時便會作為一個獨立的並發線程,這種線程在Go語言中則稱為goroutine。
goroutine 的用法如下:
//go 关键字放在方法调用前新建一个 goroutine 并执行方法体 go GetThingDone(param1, param2); //新建一个匿名方法并执行 go func(param1, param2) { }(val1, val2) //直接新建一个 goroutine 并在 goroutine 中执行代码块 go { //do someting... }
因為 goroutine 在多核心 cpu 環境下是並行的,如果程式碼區塊在多個 goroutine 中執行,那麼我們就實現了程式碼的並行。
如果需要了解程式的執行情況,怎麼拿到並行的結果呢?需配合使用channel進行。
channel
channel 是Go語言在語言層級提供的 goroutine 間的通訊方式。我們可以使用 channel 在兩個或多個 goroutine 之間傳遞訊息。
channel 是進程內的通訊方式,因此透過 channel 傳遞物件的過程和呼叫函數時的參數傳遞行為比較一致,例如也可以傳遞指標等。如果需要跨進程通信,我們建議用分散式系統的方法來解決,例如使用 Socket 或 HTTP 等通信協議。 Go語言對於網路方面也有非常完善的支援。
channel 是類型相關的,也就是說,一個 channel 只能傳遞一種類型的值,這個類型需要在宣告 channel 時指定。如果對 Unix 管道有所了解的話,就不難理解 channel,可以將其視為一種類型安全的管道。
定義channel 時,也需要定義傳送到channel 的值的類型,注意,必須使用make 建立channel,程式碼如下所示:
ci := make(chan int) cs := make(chan string) cf := make(chan interface{})
回到在Windows 和Linux 出現之前的古老年代,在開發程式時並沒有並發的概念,因為命令式程式設計語言是以串列為基礎的,程式會順序執行每一條指令,整個程式只有一個執行上下文,即一個呼叫棧,一個堆。
並發則表示程式在執行時有多個執行上下文,對應多個呼叫堆疊。我們知道每一個進程在運行時,都有自己的呼叫棧和堆,有一個完整的上下文,而作業系統在調度進程的時候,會保存被調度進程的上下文環境,等該進程獲得時間片後,再恢復該行程的上下文到系統中。
從整個作業系統層面來說,多個進程是可以並發的,那麼並發的價值何在?下面我們先看以下幾個場景。
1) 一方面我們需要靈敏回應的圖形使用者介面,一方面程式還需要執行大量的運算或 IO 密集操作,而我們需要讓介面回應與運算同時執行。
2) 當我們的 Web 伺服器面對大量使用者要求時,需要有更多的「Web 伺服器工作單元」來分別回應使用者。
3) 我們的事務處於分散式環境上,相同的工作單元在不同的電腦上處理著被分片的數據,電腦的CPU 從單核心(core)向多核心發展,而我們的程式都是串列的,電腦硬體的能力沒有發揮。
4) 我們的程式因為 IO 操作被阻塞,整個程式處於停滯狀態,其他 IO 無關的任務無法執行。
從以上幾個例子可以看到,串行程式在許多場景下無法滿足我們的要求。以下我們歸納了並發程序的幾個優點,讓大家認識並發勢在必行:
並發能更客觀地表現問題模型;
並發可以充分利用CPU 核心的優勢,提高程式的執行效率;
並發能充分利用CPU 與其他硬體設備固有的非同步性。
以上是go語言怎麼並發的詳細內容。更多資訊請關注PHP中文網其他相關文章!