有這樣一個需求,有一批學生,現在只有Name欄位,需要根據Name欄位做引數遠端請求獲取Score欄位的值。
常規寫法
type User struct {
Name string
Score int64
}
//模擬遠端呼叫資料
func Dodata(user *User) {
user.Score = int64(len(user.Name))
}
func main() {
s := CreatData()
var wg sync.WaitGroup
wg.Add(len(s)) //每個user開啟一個協程處理
for _, item := range s {
go func(i *User) {
defer wg.Done()
Dodata(i)
}(item)
}
wg.Wait()
//得到資料後下一步處理
for _, val := range s {
fmt.Println(val.Score)
}
}
當user資料為n時,需要開啟n個協程去處理。程式碼不可控。能不能指定m個協程併發處理。
func main() {
s := CreatData()
var wg sync.WaitGroup
wg.Add(10)
Handler(10, &wg, s, Dodata)//只開啟10協程去處理
wg.Wait()
//得到資料後下一步處理
for _, val := range s {
fmt.Println(val.Score)
}
}
func Handler(number int, wg *sync.WaitGroup, s []*User, workerFun func(*User)) {
inch := make(chan *User, 0)
//協程1:把需要處理的引數寫入inch
go func() {
for _, item := range s {
inch <- item
}
close(inch)
}()
//協程2:開啟number個協程,同時讀取inch的引數
for i := 0; i < number; i++ {
go func() {
defer wg.Done()
for item := range inch {
workerFun(item)
}
}()
}
}
FAN-OUT模式:
多個goroutine從同一個通道讀取資料,直到該通道關閉。OUT是一種張開的模式,所以又被稱為扇出,可以用來分發任務。
FAN-IN模式:
1個goroutine從多個通道讀取資料,直到這些通道關閉。IN是一種收斂的模式,所以又被稱為扇入,用來收集處理的結果。
本作品採用《CC 協議》,轉載必須註明作者和本文連結