golang——gorountine+channel
- 基本使用
package main
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func putNum(intChan chan int) {
for i := 1; i <= 200; i++ {
intChan <- i
}
close(intChan)
wg.Done()
}
func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) {
for num := range intChan {
flag := true
if num != 1 {
for i := 2; i < num; i++ {
if num%i == 0 {
flag = false
break
}
}
if flag {
primeChan <- num
}
}
}
exitChan <- true
wg.Done()
}
func printPrime(primeChan chan int) {
for v := range primeChan {
fmt.Println("素数是:", v)
}
wg.Done()
}
func main() {
intChan := make(chan int, 200)
primeChan := make(chan int, 200)
exitChan := make(chan bool, 16)
wg.Add(1)
go putNum(intChan)
for i := 0; i < 16; i++ {
wg.Add(1)
go primeNum(intChan, primeChan, exitChan)
}
wg.Add(1)
go printPrime(primeChan)
wg.Add(1)
go func() {
for i := 0; i < 16; i++ {
<-exitChan
}
close(primeChan)
wg.Done()
}() //匿名执行函数
wg.Wait()
}
快速知识点
- 每开启一个协程之前wg.Add(1),方法结束之后wg.Done()
- 当多个协程对同一个管道进行写入和读出的操作时,读出很快但是会等待写入完成
- 管道如果要用range进行遍历,则需要将管道关闭Close(),否则会报deadclock死锁错误,如果用for进行遍历不会出错但是建议还是要将管道关闭
- 被关闭的管道是可以被读的但是不能被写入
- 主线程比协程执行要快,所以需要设置wg.Wait()进行等待
- 单向通道
//单向通道,只能读
ch1 := make(<-chan int ,3)
//只能写
ch2 := make(chan<- int, 3)
- 多路复用
for{
select {
case v:= <-intChan:
fmt.Println(v)
case v:= <-stringChan:
fmt.Println(v)
default:
fmt.Println("读取完毕")
return
}
}
多路复用的时候不需要关闭管道
- 解决协程出现的Panic
//需要recover()宕机恢复,并且返回异常,只能在defer函数中调用
defer func(){
if err := recover();err!=nuil{
fmt.Println("出问题啦")
}
}()
本文介绍了如何在Go语言中使用goroutine和channel进行并发编程,涉及WaitGroup协调、单向与双向通道的应用、多路复用以及协程错误处理。
3838

被折叠的 条评论
为什么被折叠?



