Go併發程式設計 通道的happen before語義

2021-10-03 00:10:50 字數 1387 閱讀 6187

一、前言 在go中通道是用來解決多個goroutines之間進行同步的主要措施,在多個goroutines中,每個對通道進行寫操作的goroutine都對應著乙個從通道讀操作的goroutine。

package main

import (

"fmt"

)var c = make(chan int, 10)

var a string

func f()

func main()

package main

import (

"fmt"

)var c = make(chan int, 10)

var a string

func f()

func main()

然後在執行也可以確保輸出"hello, world"。

package main

import (

"fmt"

)var c = make(chan int)

var a string

func f()

func main()

如上**執行也可保證輸出"hello, world",注意改程式相比上乙個片段,通道改為了無緩衝,並向通道傳送資料與讀取資料的步驟(2)(4)調換了位置。

如上**如果換成有緩衝的通道,比如c = make(chan int, 1)則就不能保證一定會輸出"hello, world"。

這個規則對有緩衝通道和無緩衝通道的情況都適用,有緩衝的通道可以實現訊號量計數的功能,比如通道的容量可以認為是最大訊號量的個數,通道內當前元素個數可以認為是剩餘的訊號量個數,向通道寫入(傳送)乙個元素可以認為是獲取乙個訊號量,從通道讀取(接受)乙個元素可以認為是釋放乙個訊號量,所以有緩衝的通道可以作為限制併發數的乙個通用手段:

package main

import (

"fmt"

"time"

)var limit = make(chan int, 3)

func sayhello(index int)

var work func(int)

func main() (w,i)

}time.sleep(time.second * 10)

}

如上**main goroutine裡面為work列表裡面的每個方法的執行開啟了乙個單獨的goroutine,這裡有6個方法,正常情況下這6個goroutine可以併發執行,但是本程式使用快取大小為3的通道來做併發控制,導致同時只有3個goroutine可以併發執行。

通過上面所有的例子,不難看出解決多goroutine下共享資料可見性問題的方法是在訪問共享資料時候施加一定的同步措施。

Go語言程式設計基礎 併發 一 Go程 通道

go程 goroutine 是由go執行時管理的輕量級執行緒。啟動乙個go程並執行f x,y,z gof x,y,z package main import fmt time func fff s string func main 通道是帶有型別的管道,可以使用通道操作符 來傳送或接收值。將v傳送至...

Go語言併發程式設計 緩衝和單向通道

緩衝通道就是指乙個通道帶有乙個緩衝區,傳送資料到乙個緩衝通道只有在緩衝區滿時才被阻塞,從緩衝通道獲取資料只有在緩衝區為空時才會被阻塞。通道可以存放的資料個數為1 緩衝區容量 實現 package main import fmt strconv func main fmt.println main.o...

Go 併發程式設計

go語言宣揚用通訊的方式共享資料。go語言以獨特的併發程式設計模型傲視群雄,與併發程式設計關係最緊密的 包就是sync包,意思是同步。同步的用途有兩個,乙個是避免多個執行緒在同一時刻操作同乙個資料塊,另乙個是協調多個執行緒,以避免它們在同一時刻執行同一塊 由於這一的資料庫和 塊的背後都隱含著一種或多...