在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
理念GO语言并发模型CSP: 提倡通过通信共享内存,而非通过共享内存实现通信。 如果说
示例关闭后任然可以读取 func main() { ch := make(chan int, 2) ch <- 1 ch <- 2 close(ch) a, ok1 := <-ch b, ok2 := <-ch c, ok3 := <-ch fmt.Println(a, ok1) fmt.Println(b, ok2) fmt.Println(c, ok3) } 执行: 1 true
异常示例# 无缓冲通道导致异常 import "fmt" func baseTest() { ch := make(chan int) ch <- 10 fmt.Println("发送成功") } func main() { baseTest() } 执行:fatal error: all goroutines are asleep - deadlock! 原因:ch := make(chan int) 创建的是无缓冲通道,只有在有地接收值时才会发送成功。 # 通道无空间,继续读取 func testClose() { ch := make(chan int, 2) ch <- 1 ch <- 2 //close(ch) a, ok1 := <-ch b, ok2 := <-ch c, ok3 := <-ch fmt.Println(a, ok1) fmt.Println(b, ok2) fmt.Println(c, ok3) } 执行:fatal error: all goroutines are asleep - deadlock! # 关闭后,任往通道发送 func main() { ch := make(chan int, 2) ch <- 1 close(ch) ch <- 2 a, ok1 := <-ch b, ok2 := <-ch c, ok3 := <-ch fmt.Println(a, ok1) fmt.Println(b, ok2) fmt.Println(c, ok3) } 执行: panic: send on closed channel
#解1:无缓冲通道import "fmt" func recv(ch chan int) { ret := <- ch fmt.Println("接收成功: ", ret) } func unBuffer() { ch := make(chan int) go recv(ch) ch <- 10 fmt.Println("发送成功") } func main() { unBuffer() } 执行: 接收成功: 10 #解2:有缓冲通道import "fmt" func buffer() { ch := make(chan int, 2) ch <- 10 fmt.Println("发送成功") } func main() { buffer() } 执行: 发送成功 问题:当发送到chan大于其长度,并且没有消费时,造成死锁 import "fmt" func buffer() { ch := make(chan int, 2) ch <- 10 ch <- 11 ch <- 12 fmt.Println("发送成功") } func main() { buffer() } 执行: fatal error: all goroutines are asleep - deadlock!
综合示例读取对通道a中的数字,在通道b中平方 package main import ( "fmt" "sync" ) var wg2 sync.WaitGroup func f1(ch1 chan int) { defer wg2.Done() for i := 0; i < 100; i++ { ch1 <- i } close(ch1) } func f2(ch1, ch2 chan int) { defer wg2.Done() for { x, ok := <-ch1 if !ok { break } ch2 <- x * x } close(ch2) } func testClose() { ch := make(chan int, 2) ch <- 1 ch <- 2 close(ch) a, ok1 := <-ch b, ok2 := <-ch c, ok3 := <-ch fmt.Println(a, ok1) fmt.Println(b, ok2) fmt.Println(c, ok3) } func main() { //testClose() a := make(chan int, 100) b := make(chan int, 100) wg2.Add(2) go f1(a) go f2(a, b) wg2.Wait() for x := range b { fmt.Println(x) } } 执行: 0 ... 单向通道<-chan:只做输出的通道 chan<-:只做输入的通道 示例: 重写上面例子中f2 func f2Uni(ch1 <-chan int, ch2 chan<- int) { defer wg2.Done() for { x, ok := <-ch1 if !ok { break } ch2 <- x * x } close(ch2) }
|
请发表评论