【尚硅谷】Golang入門到實(shí)戰(zhàn)教程丨一套精通GO語言

channel管道那里,可以使用waitgroup來代替exitChan ,來判斷協(xié)程有沒有結(jié)束,讓主線程等待全部協(xié)程執(zhí)行完畢。
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup // 用于等待一組線程的結(jié)束
// 管道寫入數(shù)據(jù)
func writeData(intChan chan int) {
for i := 0; i < 50; i++ {
intChan <- i
fmt.Printf("writeData 寫入數(shù)據(jù)=%v\n", i)
}
close(intChan)
wg.Done() // 執(zhí)行完一個(gè)線程后,調(diào)用這個(gè)方法,主線程中需要等待執(zhí)行的協(xié)程數(shù)量-1
}
// 管道讀取數(shù)據(jù)
func readData(intChan chan int) {
for {
v, ok := <-intChan
if !ok {
break
}
fmt.Printf("readData 讀到數(shù)據(jù)=%v\n", v)
}
wg.Done() // 執(zhí)行完一個(gè)線程后,調(diào)用這個(gè)方法,主線程中需要等待執(zhí)行的協(xié)程數(shù)量-1
}
// 判斷是否為素?cái)?shù)
func isPrime(intChan, primeChan chan int) {
var isPrime bool // 標(biāo)識(shí)是否是素?cái)?shù)
for v := range intChan {
isPrime = true
for i := 2; i < v; i++ {
if v%i == 0 {
isPrime = false
break
}
}
if isPrime { // 如果為素?cái)?shù),則往primeChan中寫入數(shù)據(jù)
primeChan <- v
}
}
fmt.Println("isPrime 讀取素?cái)?shù)完畢")
wg.Done() // 執(zhí)行完一個(gè)協(xié)程后,調(diào)用這個(gè)方法,主線程中需要等待執(zhí)行的協(xié)程數(shù)量-1
}
func main() {
協(xié)程和管道應(yīng)用1()
協(xié)程和管道應(yīng)用2()
}
func 協(xié)程和管道應(yīng)用1() {
// 創(chuàng)建兩個(gè)管道
intChan := make(chan int, 10)
wg.Add(2) // 說明開啟了兩個(gè)線程
// 開啟了兩個(gè)協(xié)程,writeData和readData應(yīng)該是交叉執(zhí)行的
go writeData(intChan) // 開啟一個(gè)協(xié)程,往 intChan 中寫入數(shù)據(jù)
go readData(intChan) // 開啟一個(gè)協(xié)程,讀取 intChan 的數(shù)據(jù)
wg.Wait() // 告訴主線程需要等待協(xié)程執(zhí)行完畢
fmt.Println("程序執(zhí)行完畢!")
}
func 協(xié)程和管道應(yīng)用2() {
// 需求:要求統(tǒng)計(jì)1-8000的數(shù)字中,哪些是素?cái)?shù)
// 將統(tǒng)計(jì)素?cái)?shù)的任務(wù),分配給4個(gè)協(xié)程去完成
intChan := make(chan int, 1000) // 讀寫1-8000數(shù)字的管道
primeChan := make(chan int, 2000) // 存儲(chǔ)素?cái)?shù)的管道
wg.Add(5) // 下面開啟了5個(gè)協(xié)程
// 開啟寫入 1-8000 數(shù)字的協(xié)程
go func() {
for i := 1; i <= 8000; i++ {
intChan <- i
}
close(intChan)
wg.Done()
}()
// 開啟4個(gè)讀取 1-8000 數(shù)字,并統(tǒng)計(jì)素?cái)?shù)的協(xié)程
for i := 0; i < 4; i++ {
go isPrime(intChan, primeChan)
}
wg.Wait() // 等待協(xié)程執(zhí)行完畢
close(primeChan) // 關(guān)閉 primeChan 管道
// 遍歷primeChan,把結(jié)果取出來
for v := range primeChan {
fmt.Printf("素?cái)?shù)是 = %v\n", v)
}
}