您好,登錄后才能下訂單哦!
這篇文章給大家介紹Go 語言中協(xié)程通信實現(xiàn)的共享內(nèi)存是怎樣的,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
通過 goroutine 基于協(xié)程在 Go 語言中實現(xiàn)并發(fā)編程,從語法結構來說,Go 語言的協(xié)程是非常簡單的,只需要通過 go
關鍵字聲明即可,難點在于并發(fā)引起的不確定性,以及為了協(xié)調(diào)這種不確定性在不同協(xié)程間所要進行的通信,常見的并發(fā)通信模型有兩種:共享內(nèi)存和消息傳遞。
下面,我們先來看看如何通過共享內(nèi)存來實現(xiàn) Go 協(xié)程通信,并通過協(xié)程通信來重構上篇教程的代碼,實現(xiàn)應用程序的優(yōu)雅退出,新建一個 memory.go
,并編寫代碼如下:
package main
import (
"fmt"
"runtime"
"sync"
)
var counter int = 0
func add(a, b int, lock *sync.Mutex) {
c := a + b
lock.Lock()
counter++
fmt.Printf("%d: %d + %d = %d\n", counter, a, b, c)
lock.Unlock()
}
func main() {
start := time.Now()
lock := &sync.Mutex{}
for i := 0; i < 10; i++ {
go add(1, i, lock)
}
for {
lock.Lock()
c := counter
lock.Unlock()
runtime.Gosched()
if c >= 10 {
break
}
}
end := time.Now()
consume := end.Sub(start).Seconds()
fmt.Println("程序執(zhí)行耗時(s):", consume)
}
為了精確判斷主協(xié)程退出時機問題,我們需要在所有子協(xié)程執(zhí)行完畢后通知主協(xié)程,主協(xié)程在收到該信號后退出程序,通過共享內(nèi)存的方式我們引入了一個全局的 counter
計數(shù)器,該計數(shù)器被所有協(xié)程共享,每執(zhí)行一次子協(xié)程,該計數(shù)器的值加 1,當所有子協(xié)程執(zhí)行完畢后,計數(shù)器的值應該是 10,我們在主協(xié)程中通過一個死循環(huán)來判斷 counter
的值,只有當它大于等于 10 時,才退出循環(huán),進而退出整個程序。
此外,由于 counter
變量會被所有協(xié)程共享,為了避免 counter
值被污染(兩個協(xié)程同時操作計數(shù)器),我們還引入了鎖機制,即 sync.Mutex
,這是 Go 語言標準庫提供的互斥鎖,當一個 goroutine 調(diào)用其 Lock()
方法加鎖后,其他 goroutine 必須等到這個 goroutine 調(diào)用同一個 sync.Mutex
的 Unlock()
方法解鎖才能繼續(xù)訪問這個 sync.Mutex
(通過指針傳遞到子協(xié)程,所以整個應用持有的是同一個互斥鎖),我們可以通過這種方式保證所有 lock.Lock()
與 lock.Unlock()
之間的代碼是以同步阻塞方式串行執(zhí)行的,從而保證對 counter
進行讀取和更新操作時,同時只有一個協(xié)程在操作它(既保證了操作的原子性)。
最后,我們還統(tǒng)計了整個程序執(zhí)行時間。
當我們執(zhí)行這段代碼時,打印結果如下:
可以看到,實際執(zhí)行時間遠遠小于1秒,這樣一來,程序的整體執(zhí)行效率相比于上篇教程的實現(xiàn)快了將近1萬倍。
不過,代碼也因此變得更復雜,更難以維護,這還只是個簡單的加法運算實現(xiàn),就要寫這么多代碼,要引入共享變量,還要引入互斥鎖來保證操作的原子性,對于更加復雜的業(yè)務代碼,如果到處都要加鎖、解鎖,顯然對開發(fā)者和維護者來說都是噩夢,Go 語言既然以并發(fā)編程作為語言的核心優(yōu)勢,當然不至于將這樣的問題用這么繁瑣的方式來解決。
前面我們說,除了共享內(nèi)存之外,還可以通過消息傳遞來實現(xiàn)協(xié)程通信,Go 語言本身的編程哲學也是「Don’t communicate by sharing memory, share memory by communicating」,所以實際上,我們在 Go 語言并發(fā)編程實踐中,使用的都是基于消息傳遞的方式實現(xiàn)協(xié)程之間的通信。
在消息傳遞機制中,每個協(xié)程是獨立的個體,并且都有自己的變量,與共享內(nèi)存不同的是,在不同協(xié)程間這些變量不共享,每個協(xié)程的輸入和輸出都只有一種方式,那就是消息,這有點類似于進程:每個進程都是獨立的,不會被其他進程打擾,不同進程間靠消息來通信,它們不會共享內(nèi)存。
關于Go 語言中協(xié)程通信實現(xiàn)的共享內(nèi)存是怎樣的就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。