51reboot 運維開發
golang 課程
k8s 課程
python 自動化高階課程
python 基礎實戰課程
運維前端課程
課程試聽預約請掃碼》
原子函式和互斥函式都能工作,但是依靠它們都不會讓編寫併發程式變得更簡單,更不容易出錯,或者更有趣。在 go 語言裡,你可以使用通道來傳送和接收需要共享的資源,在 goroutine 之間同步。
宣告通道時,需要指定將要被共享的資料型別,可以以通過通道共享內建型別、命名型別、結構型別和引用型別的值或者指標。
無緩衝的通道:是指接收前沒有能力儲存任何值的通道,這種型別的通道要求傳送 goroutine 和接收 goroutine 都準備好,才能完成傳送和接受操作。如果沒有同時準備好,回導致先執行傳送或接收操作的 goroutine 阻塞等待。
有快取的通道:是一種指在被接收前能儲存乙個或多個值的通道,這種型別的通道並不要求 goroutine 之間必須同時完成傳送和接收。只有在通道中沒有接收的值時,接收動作才會阻塞。只有在通道沒有可用快取區容納被傳送的值時,傳送動作才會阻塞。
無快取通道工作流程圖:
有快取通道工作流程圖:
三**示例
無快取**示例1:
package mainimport "sync"// wg1用來等待程式結束var wg1 sync.waitgroup// 無緩衝的通道必須配對操作的goroutine出現,否則會一直阻塞func main() () // 傳送訊息 c "hello" // 等待完成 wg1.wait()}
無快取通道**示例2,實現阻塞生產者消費者模式:
package mainimport ( "fmt" "time")// 生產者通過通道傳送資料func produce(p chanint) }// 消費者通過通道接收資料func consumer(c chan int) }func main()
有快取通道**示例1:
package mainfunc main()
有快取通道**示例2,模擬多人工作:
package mainimport ( "sync" "fmt" "math/rand" "time")const ( // 要使用的goroutine的數量 numbergoroutines = 4 // 要處理的工作的數量 taskload = 10)// wg用來等待程式完成var wg2 sync.waitgroupfunc main() // 增加一組要完成的工作 for post := 1; post <= taskload; post++ // 當所有工作都處理完時關閉通道,以便所有通道退出 // 當關閉通道後,goroutine依舊可以從通道接收資料,但是不能再傳送資料 close(tasks) // 等待所有工作完成 wg2.wait() }// worker作為goroutine啟動來處理,從有快取的通道傳入資料func worker(tasks chan string, worker int) // 顯示我們開始工作了 fmt.printf("worker: %d : started %s\n", worker, task) // 隨機等一段時間來完成工作 sleep := rand.int63n(100) time.sleep(time.duration(sleep) * time.millisecond) // 顯示我們完成工作了 fmt.printf("worker: %d : completed %s\n", worker, task) }}
四通道結合 select
1、select 詳解
select
借助 select 語句我們可以在乙個協程中同時等待多個通道達到就緒狀態。
2、**示例
select 簡單**示例:
package mainimport ( "fmt" "math/rand")func main() // 隨機生成0-2之間的數字 index := rand.intn(3) // 向通道傳送隨機數 chs[index] // 哪乙個通道中有值,那個對應的分支就會被執行 select }
使用 select+ 超時實現無阻塞讀寫:
package mainimport ( "time" "fmt")// 使用select+超時實現無阻塞讀寫func main() () go func() () for i := 0; i < 3; i++ }}
出處:
文章好看點這裡
go語言通道插入0 Go語言之通道
所以在多個goroutine併發中,我們不僅可以通過原子函式和互斥鎖保證對共享資源的安全訪問,消除競爭的狀態,還可以通過使用通道,在多個goroutine傳送和接受共享的資料,達到資料同步的目的。通道,它有點像在兩個routine之間架設的管道 乙個goroutine可以往這個管道裡塞資料,另外乙個...
go語言通道插入0 Go語言帶緩衝的通道
go語言中有緩衝的通道 bufferedchannel 是一種在被接收前能儲存乙個或者多個值的通道。這種型別的通道並不強制要求goroutine之間必須同時完成傳送和接收。通道會阻塞傳送和接收動作的條件也會不同。只有在通道中沒有要接收的值時,接收動作才會阻塞。只有在通道沒有可用緩衝區容納被傳送的值時...
go語言通道插入0 Go 語言的併發性
昨天,我在 quora 上回答了乙個關於 go 語言併發模型的問題。現在,我覺得我還想再多說些什麼!併發性是 go 語言中最強大的特性之一。許多人討論了這個話題,從非常簡單到過於複雜的都有。今天,我也來說說我的看法。go 語言的併發性是一種思維方式而不僅僅是乙個語法。為了利用 go 的強大功能,你需...