channel(3) 一 基本定义
1.channel概念:
类似管道pipe
先进先出
线程安全,多个goroutine同时访问,不需要加锁
channel是有类型的,整数类型的channel只能存放整数类型的数据
2.channel声明
var 变量名 chan 类型
var test chan int
var test chan string
var test chan map[string]string
var test chan stu
var test chan *stu
3.channel类似于map,slice必须进行初始化
var test chan int
test = make(chan int,100) //在这里如果容量为0,会是什么结果呢?
4.channel接收数据和读取数据
intchan <-10 //把数据发送到管道中
result := <- intchan //从channel中读取数据,并赋值给result
接上面的疑问,如果容量为0,会是什么情况呢?还有一些问题来一一验证
没有初始化的情况:(报错 nil chan)
import(
"fmt"
)
func main() {
var c chan int
c <- 10
result:= <- c
fmt.Println(result) //goroutine 1 [chan send (nil chan)]:
}
初始化后,容量 为0:
import(
"fmt"
)
func main() {
var c chan int
c = make(chan int,0)
c <- 10
result:= <- c
fmt.Println(result)
/*
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
c:/goclass/src/day8goroutine/channel/main.go:9 +0x60
exit status 2
*/
}
还是报错,不太明显,我们换一种方法来测试:
import(
"fmt"
"time"
)
func main() {
var c chan int
c = make(chan int,0)
go func(){ //开启一个goroutine
fmt.Println("start input to the channel")
c <- 10
fmt.Println("end input to the channel")
}()
time.Sleep(time.Second*100)
result:= <- c
fmt.Println(result)
}
//运行结果,会立马输出“start input to the channel” 这一行,然后等待100s后,会输入result结果10。因为容量为0的话,指的是channel没有缓存容量 ,就是不能够缓存任何数据,如果容量改为1的话,会立马输出start和end两句话。
5.channel 权限控制
var intchan chan <- int //intchan只可接收int类型数据
var intchan <- chan int //只可以从intchan中读取数据
var intchan chan int //即可以接收也可也读取数据
package main
import(
"fmt"
"sync"
)
var waitgroup sync.WaitGroup
func SendDate(c chan <- string){ //往chan中写入数据,这个类型是只写的
c <- "beijing"
c <- "shanghai"
c <- "guangzhou"
c <- "shenzhen"
close(c) //写完数据关闭channel
waitgroup.Done()
}
func GetDate(c <- chan string){ //读取chan中的数据,这个类型是只读的
for {
input,ok :=<-c //检查channel 是否关闭
if !ok{
fmt.Println("the chan is closed")
break
}
fmt.Println(input)
}
waitgroup.Done()
}
func main() {
c := make(chan string)
waitgroup.Add(2)
go SendDate(c)
go GetDate(c)
waitgroup.Wait() //等待所有的goroutine执行完成
}
上面的代码中有权限的控制,goroutine和chan相结合。还有一个检查chan是否关闭
input,ok := <-c
遍历chan中的元素:
for input := range c{
fmt.Println(input)
}

浙公网安备 33010602011771号