声明和存取
channel,是一种带有类型的管道引用类型
使用前需要make(Type, (缓冲容量))
不带缓冲区的管道必须结合协程使用
可以查看长度len和容量cap
package main
import "fmt"
func main() {
// 声明一个string信道,容量为2
var ch chan string = make(chan string, 2)
ch <- "枫枫" // 写入数据到信道中
ch <- "知道"
s := <-ch // 从信道读取数据
fmt.Println(s)
ss, ok := <-ch
fmt.Println(ss, ok)
close(ch)
}
存入:channel <- value
取出:value, (ok) <- channel
丢弃:<- channel
先进先出,自动阻塞
数据需要保持流动,否则会阻死报错
搭配协程使用
package main
import "fmt"
func pushNum(c chan int) {
for i := 0; i < 100; i++ {
c <- i
}
close(c) // 写完必须要关闭,不然会死锁
}
func main() {
var c1 chan int = make(chan int, 2) // 2表示缓冲区大小
go pushNum(c1)
for value := range c1 {
fmt.Println(value)
}
}
多个协程函数,close就不能写在协程函数里了
package main
import (
"fmt"
"sync"
)
var ch chan int = make(chan int, 10)
var wg = sync.WaitGroup{}
func pushNum() {
for i := 0; i < 5; i++ {
ch <- i
}
wg.Done()
}
func main() {
wg.Add(2)
go pushNum()
go pushNum()
wg.Wait()
close(ch)
for {
res, ok := <-ch
if !ok {
break
}
fmt.Println(res)
}
}
close
使用close之后就不能在继续写入了,但是还可以继续从缓冲区读取
- close之后,读取的chan是数据类型的默认值
- close之后,不能再往chan里面写入数据
- for range之前必须要close
可读可写
package main
import "fmt"
func main() {
var ch chan int = make(chan int, 2)
// 可读chan
var readCh <-chan int = ch
// 可写chan
var writeCh chan<- int = ch
writeCh <- 1
writeCh <- 2
fmt.Println(<-readCh)
fmt.Println(<-readCh)
}
select ... case
适用于无法确认合适关闭信道的情况
通常结合for循环使用
select ... case会阻塞到某个分支可以继续执行时执行该分支,当没有可执行的分支是执行default分支
package main
import "fmt"
func main() {
var ch1 chan int = make(chan int, 2)
var ch2 chan int = make(chan int, 2)
var ch3 chan int = make(chan int, 2)
ch1 <- 1
ch2 <- 2
ch3 <- 3
select {
// 监听多个chan的情况,是随机执行
case v := <-ch1:
fmt.Println(v)
case v := <-ch2:
fmt.Println(v)
case v := <-ch3:
fmt.Println(v)
default:
fmt.Println("没有数据")
}
}
package main
import "fmt"
func PrimeNum(n int, c chan int) {
for i := 2; i < n; i++ {
if n%i == 0 {
return
}
}
c <- n
}
func main() {
c := make(chan int)
for i := 2; i < 100001; i++ {
go PrimeNum(i, c)
}
Print:
for {
select {
case v := <-c:
fmt.Printf("%v\t", v)
default:
fmt.Printf("所有素数都已被找到")
break Print
}
}
}