channel管道Channel是Go中的一个核心类型,你可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication),下面我们就来说一说关于go语言进阶?我们一起去了解并探讨一下这个问题吧!
go语言进阶
channel管道
Channel是Go中的一个核心类型,你可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication)。
它的操作符是箭头 <-
创建channel
msg := make(chan string 3)
数据写入channel
msg <- "你好"
msg <- "在吗"
读取channel
message := <-msg
fmt.Println(message)
fmt.Println(<-msg)
读取结果:你好 在吗
channel 结合gorouting
package main
import (
"fmt"
"time"
)
func main() {
msg := make(chan int, 3)
go test(msg)
//写入数据
for i := 0; i < 10; i {
msg <- i
fmt.Println("写入数据", i)
time.Sleep(time.Second * 1)
}
}
func test(m chan int) {
for {
//不停的读取
fmt.Println("读取数据", <-m)
}
}
运行结果:
写入数据 0
读取数据 0
写入数据 1
读取数据 1
写入数据 2
读取数据 2
写入数据 3
读取数据 3
写入数据 4
读取数据 4
写入数据 5
读取数据 5
写入数据 6
读取数据 6
写入数据 7
读取数据 7
写入数据 8
读取数据 8
写入数据 9
读取数据 9
这里需要注意一下make(chan int, 3) 这个语法意思是管道中有三个缓存int空间,当这个缓存赛满了,就需要阻塞,等待另一个线程取出数据后再写入。
channel的关闭
close(管道名)
package main
import (
"fmt"
"time"
)
func main() {
msg := make(chan int, 3)
go test(msg)
//写入数据
for i := 0; i < 10; i {
msg <- i
fmt.Println("写入数据", i)
time.Sleep(time.Second * 1)
}
close(msg) //关闭管道
}
func test(m chan int) {
for {
//不停的读取
data, ok := <-m
if ok == true {
fmt.Println("读取数据", data)
} else {
break
}
}
}
channel和range
range可以更方便的读取管道中的数据
把上面的test方法修改一下
func test(m chan int) {
for i := range m {
fmt.Println("读取数据:", i)
}
}
channel 和select
如果有同时多个case去处理,比如同时有多个channel可以接收数据,那么Go会伪随机的选择一个case处理(pseudo-random)。如果没有case需要处理,则会选择default去处理,如果default case存在的情况下。如果没有default case,则select语句会阻塞,直到某个case需要处理。
import "fmt"
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x y
case <-quit:
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit)
}