新聞中心
有人把Go語言比作 21 世紀(jì)的C語言,第一是因?yàn)镚o語言設(shè)計(jì)簡單,第二則是因?yàn)?21 世紀(jì)最重要的就是并發(fā)程序設(shè)計(jì),而 Go 從語言層面就支持并發(fā)。同時(shí)實(shí)現(xiàn)了自動垃圾回收機(jī)制。

創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供揚(yáng)州網(wǎng)站建設(shè)、揚(yáng)州做網(wǎng)站、揚(yáng)州網(wǎng)站設(shè)計(jì)、揚(yáng)州網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、揚(yáng)州企業(yè)網(wǎng)站模板建站服務(wù),十載揚(yáng)州做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
Go語言的并發(fā)機(jī)制運(yùn)用起來非常簡便,在啟動并發(fā)的方式上直接添加了語言級的關(guān)鍵字就可以實(shí)現(xiàn),和其他編程語言相比更加輕量。
下面來介紹幾個(gè)概念:
進(jìn)程/線程
進(jìn)程是程序在操作系統(tǒng)中的一次執(zhí)行過程,系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位。
線程是進(jìn)程的一個(gè)執(zhí)行實(shí)體,是 CPU 調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位。
一個(gè)進(jìn)程可以創(chuàng)建和撤銷多個(gè)線程,同一個(gè)進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行。
并發(fā)/并行
多線程程序在單核心的 cpu 上運(yùn)行,稱為并發(fā);多線程程序在多核心的 cpu 上運(yùn)行,稱為并行。
并發(fā)與并行并不相同,并發(fā)主要由切換時(shí)間片來實(shí)現(xiàn)“同時(shí)”運(yùn)行,并行則是直接利用多核實(shí)現(xiàn)多線程的運(yùn)行,Go程序可以設(shè)置使用核心數(shù),以發(fā)揮多核計(jì)算機(jī)的能力。
協(xié)程/線程
協(xié)程:獨(dú)立的棧空間,共享堆空間,調(diào)度由用戶自己控制,本質(zhì)上有點(diǎn)類似于用戶級線程,這些用戶級線程的調(diào)度也是自己實(shí)現(xiàn)的。
線程:一個(gè)線程上可以跑多個(gè)協(xié)程,協(xié)程是輕量級的線程。
優(yōu)雅的并發(fā)編程范式,完善的并發(fā)支持,出色的并發(fā)性能是Go語言區(qū)別于其他語言的一大特色。使用Go語言開發(fā)服務(wù)器程序時(shí),就需要對它的并發(fā)機(jī)制有深入的了解。
Goroutine 介紹
goroutine 是一種非常輕量級的實(shí)現(xiàn),可在單個(gè)進(jìn)程里執(zhí)行成千上萬的并發(fā)任務(wù),它是Go語言并發(fā)設(shè)計(jì)的核心。
說到底 goroutine 其實(shí)就是線程,但是它比線程更小,十幾個(gè) goroutine 可能體現(xiàn)在底層就是五六個(gè)線程,而且Go語言內(nèi)部也實(shí)現(xiàn)了 goroutine 之間的內(nèi)存共享。
使用 go 關(guān)鍵字就可以創(chuàng)建 goroutine,將 go 聲明放到一個(gè)需調(diào)用的函數(shù)之前,在相同地址空間調(diào)用運(yùn)行這個(gè)函數(shù),這樣該函數(shù)執(zhí)行時(shí)便會作為一個(gè)獨(dú)立的并發(fā)線程,這種線程在Go語言中則被稱為 goroutine。
goroutine 的用法如下:
//go 關(guān)鍵字放在方法調(diào)用前新建一個(gè) goroutine 并執(zhí)行方法體
go GetThingDone(param1, param2);
//新建一個(gè)匿名方法并執(zhí)行
go func(param1, param2) {
}(val1, val2)
//直接新建一個(gè) goroutine 并在 goroutine 中執(zhí)行代碼塊
go {
//do someting...
}因?yàn)?goroutine 在多核 cpu 環(huán)境下是并行的,如果代碼塊在多個(gè) goroutine 中執(zhí)行,那么我們就實(shí)現(xiàn)了代碼的并行。
如果需要了解程序的執(zhí)行情況,怎么拿到并行的結(jié)果呢?需要配合使用channel進(jìn)行。
channel
channel 是Go語言在語言級別提供的 goroutine 間的通信方式。我們可以使用 channel 在兩個(gè)或多個(gè) goroutine 之間傳遞消息。
channel 是進(jìn)程內(nèi)的通信方式,因此通過 channel 傳遞對象的過程和調(diào)用函數(shù)時(shí)的參數(shù)傳遞行為比較一致,比如也可以傳遞指針等。如果需要跨進(jìn)程通信,我們建議用分布式系統(tǒng)的方法來解決,比如使用 Socket 或者 HTTP 等通信協(xié)議。Go語言對于網(wǎng)絡(luò)方面也有非常完善的支持。
channel 是類型相關(guān)的,也就是說,一個(gè) channel 只能傳遞一種類型的值,這個(gè)類型需要在聲明 channel 時(shí)指定。如果對 Unix 管道有所了解的話,就不難理解 channel,可以將其認(rèn)為是一種類型安全的管道。
定義一個(gè) channel 時(shí),也需要定義發(fā)送到 channel 的值的類型,注意,必須使用 make 創(chuàng)建 channel,代碼如下所示:
ci := make(chan int)
cs := make(chan string)
cf := make(chan interface{})回到在 Windows 和 Linux 出現(xiàn)之前的古老年代,在開發(fā)程序時(shí)并沒有并發(fā)的概念,因?yàn)槊钍匠绦蛟O(shè)計(jì)語言是以串行為基礎(chǔ)的,程序會順序執(zhí)行每一條指令,整個(gè)程序只有一個(gè)執(zhí)行上下文,即一個(gè)調(diào)用棧,一個(gè)堆。
并發(fā)則意味著程序在運(yùn)行時(shí)有多個(gè)執(zhí)行上下文,對應(yīng)著多個(gè)調(diào)用棧。我們知道每一個(gè)進(jìn)程在運(yùn)行時(shí),都有自己的調(diào)用棧和堆,有一個(gè)完整的上下文,而操作系統(tǒng)在調(diào)度進(jìn)程的時(shí)候,會保存被調(diào)度進(jìn)程的上下文環(huán)境,等該進(jìn)程獲得時(shí)間片后,再恢復(fù)該進(jìn)程的上下文到系統(tǒng)中。
從整個(gè)操作系統(tǒng)層面來說,多個(gè)進(jìn)程是可以并發(fā)的,那么并發(fā)的價(jià)值何在?下面我們先看以下幾種場景。
1) 一方面我們需要靈敏響應(yīng)的圖形用戶界面,一方面程序還需要執(zhí)行大量的運(yùn)算或者 IO 密集操作,而我們需要讓界面響應(yīng)與運(yùn)算同時(shí)執(zhí)行。
2) 當(dāng)我們的 Web 服務(wù)器面對大量用戶請求時(shí),需要有更多的“Web 服務(wù)器工作單元”來分別響應(yīng)用戶。
3) 我們的事務(wù)處于分布式環(huán)境上,相同的工作單元在不同的計(jì)算機(jī)上處理著被分片的數(shù)據(jù),計(jì)算機(jī)的 CPU 從單內(nèi)核(core)向多內(nèi)核發(fā)展,而我們的程序都是串行的,計(jì)算機(jī)硬件的能力沒有得到發(fā)揮。
4) 我們的程序因?yàn)?IO 操作被阻塞,整個(gè)程序處于停滯狀態(tài),其他 IO 無關(guān)的任務(wù)無法執(zhí)行。
從以上幾個(gè)例子可以看到,串行程序在很多場景下無法滿足我們的要求。下面我們歸納了并發(fā)程序的幾條優(yōu)點(diǎn),讓大家認(rèn)識到并發(fā)勢在必行:
- 并發(fā)能更客觀地表現(xiàn)問題模型;
- 并發(fā)可以充分利用 CPU 核心的優(yōu)勢,提高程序的執(zhí)行效率;
- 并發(fā)能充分利用 CPU 與其他硬件設(shè)備固有的異步性。
本文名稱:創(chuàng)新互聯(lián)GO教程:Go語言并發(fā)簡述(并發(fā)的優(yōu)勢)
鏈接分享:http://fisionsoft.com.cn/article/djehjed.html


咨詢
建站咨詢
