一文了解Go 并發(fā)與并行
Go語言,由Google的Robert Griesemer、Rob Pike和Ken Thompson于2009年開發(fā),是一種靜態(tài)類型、垃圾回收、多線程并發(fā)的編程語言。Go語言的設(shè)計(jì)目標(biāo)是簡(jiǎn)單、高效、易于使用。它的并發(fā)模型非常強(qiáng)大,可以輕松地處理大量并發(fā)任務(wù),這使得Go語言成為現(xiàn)代高性能并發(fā)應(yīng)用的理想選擇。
在Go語言(Golang)中,并發(fā)(Concurrency)和并行(Parallelism)是兩個(gè)既有聯(lián)系又有所區(qū)別的概念
并發(fā)(Concurrency)
并發(fā)指的是在一段時(shí)間內(nèi),多個(gè)任務(wù)能夠開始、執(zhí)行和完成,這些任務(wù)在宏觀上看起來是同時(shí)進(jìn)行的,盡管在微觀層面上它們可能并不是真正的同時(shí)執(zhí)行。Go語言通過goroutines(輕量級(jí)線程)和channels(用于goroutines間通信的安全通道)來支持高效率的并發(fā)編程。并發(fā)的重點(diǎn)在于任務(wù)的組織和管理,使得即使在單個(gè)CPU核心上,也能通過時(shí)間切片和任務(wù)調(diào)度,給予用戶多個(gè)任務(wù)同時(shí)進(jìn)行的錯(cuò)覺。
并行(Parallelism)
并行則是指在物理上或邏輯上的多個(gè)處理器(或多核CPU)同時(shí)執(zhí)行多個(gè)任務(wù)。當(dāng)程序能夠充分利用多核處理器的多個(gè)核心,使得不同的任務(wù)或任務(wù)的部分確實(shí)同時(shí)在不同的處理器上執(zhí)行,這就是并行。Go語言的運(yùn)行時(shí)能夠自動(dòng)利用多核處理器,使得當(dāng)有足夠的goroutines需要運(yùn)行時(shí),它們可以被分配到不同的CPU核心上并行執(zhí)行,從而提升程序的執(zhí)行效率。
goroutine的實(shí)現(xiàn)原理
goroutine的實(shí)現(xiàn)原理主要依賴于Go語言的運(yùn)行時(shí)(runtime)和調(diào)度器(scheduler)。當(dāng)我們創(chuàng)建一個(gè)goroutine時(shí),運(yùn)行時(shí)會(huì)為其分配一個(gè)獨(dú)立的??臻g,并將其加入到調(diào)度器的運(yùn)行隊(duì)列中。調(diào)度器會(huì)根據(jù)goroutine的優(yōu)先級(jí)和狀態(tài)(運(yùn)行、休眠、阻塞等)來調(diào)度它們的執(zhí)行。
channel的實(shí)現(xiàn)原理
channel的實(shí)現(xiàn)原理主要依賴于Go語言的運(yùn)行時(shí)和內(nèi)存模型。當(dāng)我們創(chuàng)建一個(gè)channel時(shí),運(yùn)行時(shí)會(huì)為其分配一個(gè)緩沖區(qū),用于存儲(chǔ)數(shù)據(jù)。channel的讀寫操作是原子的,這意味著它們不會(huì)被中斷。當(dāng)一個(gè)goroutine向channel中寫入數(shù)據(jù)時(shí),運(yùn)行時(shí)會(huì)將數(shù)據(jù)放入緩沖區(qū),并通知其他goroutine。當(dāng)一個(gè)goroutine從channel中讀取數(shù)據(jù)時(shí),運(yùn)行時(shí)會(huì)從緩沖區(qū)中取出數(shù)據(jù),并通知其他goroutine。
關(guān)系與區(qū)別
- 區(qū)別:并發(fā)關(guān)注的是任務(wù)的執(zhí)行方式和任務(wù)間的協(xié)作,能夠在單核或多核環(huán)境下工作,不保證任務(wù)絕對(duì)同時(shí)執(zhí)行。而并行關(guān)注的是任務(wù)的實(shí)際同時(shí)執(zhí)行,需要多核環(huán)境來實(shí)現(xiàn)。
- 聯(lián)系:并發(fā)是并行的基礎(chǔ),沒有并發(fā)就沒有并行。并發(fā)使得程序能夠在邏輯上分解為多個(gè)獨(dú)立執(zhí)行的單元,而并行則是在硬件層面實(shí)現(xiàn)這些單元的同時(shí)執(zhí)行,從而達(dá)到更高的性能。
for i := 1; i <= 10; i++ { go func() { fmt.Println("123") }() }
這段代碼展示了Go語言中并發(fā)的特性。for
循環(huán)與通過go
關(guān)鍵字啟動(dòng)的goroutines之間是并發(fā)執(zhí)行的。具體分析如下:
并發(fā)性: 當(dāng)
for
循環(huán)每次迭代時(shí),它都會(huì)啟動(dòng)一個(gè)新的goroutine并通過go func() {...}()
表達(dá)式。這意味著循環(huán)繼續(xù)進(jìn)行下一次迭代時(shí),剛啟動(dòng)的goroutine幾乎立刻開始執(zhí)行,無需等待前一個(gè)goroutine完成。因此,這些goroutine的執(zhí)行是并發(fā)的——它們的執(zhí)行在時(shí)間上重疊,不過實(shí)際的執(zhí)行順序取決于Go運(yùn)行時(shí)的調(diào)度策略和可用的處理器核心。并行性: 是否并行執(zhí)行(即是否同時(shí)在多個(gè)處理器核心上執(zhí)行)則取決于運(yùn)行時(shí)環(huán)境和當(dāng)前系統(tǒng)的負(fù)載。如果系統(tǒng)有多個(gè)處理器核心且goroutines的數(shù)量足夠多以至于它們不能全部在一個(gè)核心上高效執(zhí)行,Go的調(diào)度器可能會(huì)將這些goroutine分布在不同的核心上并行執(zhí)行。然而,對(duì)于這段特定的代碼,由于goroutine內(nèi)的工作非常輕(僅打印一個(gè)空字符串),并行收益不大,甚至可能全部在一個(gè)核心上順序快速執(zhí)行完,因?yàn)閱?dòng)goroutine和打印操作都非??臁?/p>
總結(jié)來說,這段代碼展示了并發(fā)執(zhí)行,而并行性取決于運(yùn)行時(shí)的具體情況,但就這個(gè)簡(jiǎn)單的示例而言,并行效果可能不明顯。
到此這篇關(guān)于一文了解Go 并發(fā)與并行的文章就介紹到這了,更多相關(guān)Go 并發(fā)與并行內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go 異常處理panic和recover的簡(jiǎn)單實(shí)踐
在Go語言中,異常處理主要通過panic和recover這兩個(gè)內(nèi)建函數(shù)來實(shí)現(xiàn),本文主要介紹了go異常處理panic和recover的簡(jiǎn)單實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2025-04-04Go基礎(chǔ)教程系列之WaitGroup用法實(shí)例詳解
這篇文章主要介紹了Go基礎(chǔ)教程系列之WaitGroup用法實(shí)例詳解,需要的朋友可以參考下2022-04-04Go語言中實(shí)現(xiàn)完美錯(cuò)誤處理實(shí)踐分享
Go?語言是一門非常流行的編程語言,由于其高效的并發(fā)編程和出色的網(wǎng)絡(luò)編程能力,越來越受到廣大開發(fā)者的青睞。本文我們就來深入探討一下Go?語言中的錯(cuò)誤處理機(jī)制吧2023-04-04