Go語言通道之緩沖通道
前文為大家講解了Go語言通道之無緩沖通道
有緩沖的通道相比于無緩沖通道,多了一個緩存的功能,如下圖描述的一樣:

從圖上可以明顯看到和無緩沖通道的區(qū)別,無緩沖必須兩個Goroutine都進(jìn)入通道才能進(jìn)行數(shù)據(jù)的交換,這個不用,如果數(shù)據(jù)有,直接就能拿走。
package ChannelDemo
import (
"fmt"
"math/rand"
"sync"
"time"
)
const (
numberGoroutines = 4
taskLoad = 10
)
var bufferWg sync.WaitGroup
func init() {
rand.Seed(time.Now().Unix())
}
func main() {
//創(chuàng)建了一個10任務(wù)的緩沖通道
tasks := make(chan string, taskLoad)
bufferWg.Add(numberGoroutines)
//創(chuàng)建4個Goroutine
for gr := 1; gr <= numberGoroutines; gr++ {
go worker(tasks, gr)
}
//向緩沖通道中放入數(shù)據(jù)
for post := 1; post <= taskLoad; post++ {
tasks <- fmt.Sprintf("Task : %d", post)
}
close(tasks)
bufferWg.Wait()
}
func worker(tasks chan string, worker int) {
defer bufferWg.Done()
for {
task, ok := <-tasks
if !ok {
fmt.Printf("Worker: %d : 結(jié)束工作 \n", worker)
return
}
fmt.Printf("Worker: %d : 開始工作 %s\n", worker, task)
//隨機(jī)處理一下工作的時間
sleep := rand.Int63n(100)
time.Sleep(time.Duration(sleep) * time.Millisecond)
fmt.Printf("Worker: %d : 完成工作 %s\n", worker, task)
}
}運(yùn)行結(jié)果:
Worker: 3 : 開始工作 Task : 4
Worker: 2 : 開始工作 Task : 2
Worker: 1 : 開始工作 Task : 1
Worker: 4 : 開始工作 Task : 3
Worker: 4 : 完成工作 Task : 3
Worker: 4 : 開始工作 Task : 5
Worker: 2 : 完成工作 Task : 2
Worker: 2 : 開始工作 Task : 6
Worker: 3 : 完成工作 Task : 4
Worker: 3 : 開始工作 Task : 7
Worker: 1 : 完成工作 Task : 1
Worker: 1 : 開始工作 Task : 8
Worker: 3 : 完成工作 Task : 7
Worker: 3 : 開始工作 Task : 9
Worker: 1 : 完成工作 Task : 8
Worker: 1 : 開始工作 Task : 10
Worker: 4 : 完成工作 Task : 5
Worker: 4 : 結(jié)束工作
Worker: 3 : 完成工作 Task : 9
Worker: 3 : 結(jié)束工作
Worker: 2 : 完成工作 Task : 6
Worker: 2 : 結(jié)束工作
Worker: 1 : 完成工作 Task : 10
Worker: 1 : 結(jié)束工作
因?yàn)槟囊粋€worker先從通道中取值有系統(tǒng)自己進(jìn)行調(diào)度的,所以每次運(yùn)行的結(jié)果稍微不同,但是相同的是10個任務(wù)被4個協(xié)程有條不紊的完成了
注意:main中有一句代碼 Close(tasks) 關(guān)閉通道的代碼非常重要。當(dāng)通道關(guān)閉后,goroutine 依舊可以從通道接收數(shù)據(jù),但是不能再向通道里發(fā)送數(shù)據(jù)。
能夠從已經(jīng)關(guān)閉的通道接收數(shù)據(jù)這一點(diǎn)非常重要,因?yàn)檫@允許通道關(guān)閉后依舊能取出其中緩沖的全部值,而不會有數(shù)據(jù)丟失.
總結(jié)
無緩沖的通道保證同時交換數(shù)據(jù),而有緩沖的通道不做這種保證。
到此這篇關(guān)于Go語言通道之緩沖通道的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Go語言實(shí)現(xiàn)基于websocket瀏覽器通知功能
這篇文章主要介紹了Go語言實(shí)現(xiàn)基于websocket瀏覽器通知功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
golang實(shí)現(xiàn)命令行程序的使用幫助功能
這篇文章介紹了golang實(shí)現(xiàn)命令行程序使用幫助的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07
Go語言關(guān)于幾種深度拷貝(deepcopy)方法的性能對比
這篇文章主要介紹了Go語言關(guān)于幾種深度拷貝(deepcopy)方法的性能對比,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
Golang時間及時間戳的獲取轉(zhuǎn)換超全面詳細(xì)講解
說實(shí)話,golang的時間轉(zhuǎn)化還是很麻煩的,最起碼比php麻煩很多,下面這篇文章主要給大家介紹了關(guān)于golang時間/時間戳的獲取與轉(zhuǎn)換的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12

