併發之通道

2021-08-29 04:35:03 字數 2226 閱讀 6143

在go 語言裡,我們不僅可以使用原子函式和互斥鎖來保證對共享資源的安全訪問以及消除競爭狀態,還可以使用通道。通過傳送和接收需要共享的資源,在 goroutine 之間做同步。我們通過通道可以共享內建型別、命名型別、結構型別和引用型別的值或者指標。

// 建立無緩衝的整型通道

unbuffered :=

make

(chan

int)

// 建立有緩衝的字串通道

buffered :=

make

(chan

string,10

)// 通過通道傳送乙個字串

buffered <-

"gopher"

// 從通道接收乙個字串

value :=

<-buffered

1、無緩衝的通道

無緩衝的通道是指在接收前沒有能力儲存任何值的通道。這種型別的通道要求傳送 goroutine 和接收 goroutine 同時準備好,才能完成傳送和接收操作。如果兩個 goroutine 沒有同時準備好,通道會導致先執行傳送或者接收的通道的 goroutine 阻塞等待。這種對通道進行傳送和接收的互動行為本身就是同步的。其中任意乙個操作都無法離開另乙個操作單獨存在。

如下面**,就是利用無緩衝通道實現的網球比賽

package main

import

("fmt"

"math/rand"

"sync"

"time"

)var wg sync.waitgroup

func

init()

func

main()

func

player

(name string

, count chan

int)

n := rand.

intn

(100

)if n %

13==

0 fmt.

printf

("%s hit the ball: %d \n"

, name, ball)

ball++

count <- ball

}}

2、有緩衝的通道

有緩衝的通道是一種在被接收前能儲存乙個或者多個值的通道。這種型別的通道並不強制要求 goroutine 之間必須同時完成傳送和接收。只有在通道中沒有要接收的值時,接收動作才會阻塞。只有通道中沒有可用的緩衝區容納被傳送的數值時,傳送動作才會阻塞。則有緩衝通道與無緩衝通道之間的乙個很大的不同就是:無緩衝的通道保證進行傳送和接收的 goroutine 會在同一時間進行資料交換;有緩衝的通道則沒有這種保證。

package main

import

("fmt"

"math/rand"

"sync"

"time"

)const

( goroutinenums =

4 taskload =10)

var wg sync.waitgroup

func

init()

func

main()

for post :=

0; post < taskload; post++

close

(task)

wg.wait()

}func

worker

(task chan

string

, worker int

) fmt.

printf

("worker %d start %s \n"

,worker, value)

sleep := rand.

int63n

(100

) time.

sleep

(time.

duration

(sleep)

) fmt.

printf

("worker %d finish %s \n"

,worker, value)

}}

從上面的**可知,當通道關閉後,goroutine 依舊可以從通道接收資料,但是不能再向通道裡傳送資料。同時要注意的是,從乙個已經關閉且沒有任何資料的通道裡獲取資料,總會立刻返回,並返回乙個通道型別的零值,此時,當從通道裡面獲取資料時,應該獲取其狀態值,再使用其資料。

Golang併發 goroutine和通道

goroutine 和通道 channel 實現的通訊順序程序 csp 模式 共享記憶體多執行緒模式 goroutine goroutine指每乙個併發執行的活動。main函式在主goroutine中執行。goroutine通過go關鍵字建立。gof 新建乙個goroutine呼叫f go語句本身立...

Golang併發以及通道的使用

golang最擅長的就是併發程式設計,使用golang可以很方便的進行併發程式設計。先看一段普通的 package main import fmt time func foo i int func main 輸出為 0 will sleep 0 wake up 1 will sleep 1 wake...

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

一 前言 在go中通道是用來解決多個goroutines之間進行同步的主要措施,在多個goroutines中,每個對通道進行寫操作的goroutine都對應著乙個從通道讀操作的goroutine。package main import fmt var c make chan int,10 var a...