本文主要总结了在学习channel的时候一些用法的汇总
channel的定义:make(chan string):
ch:= make(chan string)
channel同步,数据传递:
写端: ch<- “hello” ---- 写端写数据,读端不在读,阻塞
读端 : buf := <-ch ---- 读端读数据,同时写端不再写,读端阻塞
len(ch) : channel中剩余未读取数据个数。cap(ch) :通道的容量
无缓冲channel :
通道容量为0,len=0.
channel 应用于两个go程中。一个读,另一个写
具备同步能力。读、写同步
有缓冲的channel: (此时就不是同步操作了,而变成异步操作了)
通道容量为非0。 len(ch) : channel中剩余未读取数据个数。cap(ch):通道的容量。
channel 应用于两个go程中。一个读,另一个写。
缓冲区可以进行数据存储。存储至容量上限-》阻塞。具备异步能力,不需同时操作channel缓冲区(发短信)
关闭channel :
确定不再向对端发送、接受数据时,可使用close(ch) 来关闭channel
对端可以判断channel是否关闭
if num,ok := <- ch;ok ==true{
//如果对端已经关闭,ok-->false
//如果对端没有关闭,ok-->true
}
也可以使用range 替代ok :for num:= range ch{ //ch不能替换为<-ch ; fmt.Println("读到数据:",num) }
总结:1.数据未发完,不应该关闭 。2.已经关闭的channel,不可以再往内写入数据。3.channel关闭后依然可以读,但是读到的是0 — 说明写端关闭
下面给出一个案例
package main
import (
"fmt"
"time"
)
func main(){
ch := make(chan int)
go func() {
for i:=0;i<8;i++{
ch <- i
}
close(ch) //写端,写完数据主动关闭
fmt.Println("写完")
}()
time.Sleep(6*time.Second)
for{
if num,ok:= <- ch;ok==true{
fmt.Println("读到数据:",num)
}else {
break
}
}
第二种
for num:= range ch{
fmt.Println("读到数据:",num) //只是遍历channel中的数据
}
}
单向channel:
默认的channel是双向的. ch := make(chan 类型) / var ch chan int
单向写channel : var sendCh chan <- int / sendCh = make(chan <- int)
单向读channel : var revc <- chan int / recvCh = make(<- chan int)
转换:
1.双向channel可以隐式转换为 任意一种单项channel
sendCh = ch
2.单向channel不能转换为 双向channel
ch = sendCh/recvCh error!!!
传参:传引用
定时器:
Timer: 创建定时器,指定定时时长,定时到达后。系统自动向定时器的成员 C 写系统当前时间(对chan进行写操作)
type Timer struct{
C <- chan Time
r runtimeTimer
}
读取Timer.C 得到定时后的系统时间。并完成一次channel的读操作。
func main(){
fmt.Println("当前时间:",time.Now())
//创建定时器
MyTimer := time.NewTimer(time.Second*3)
nowTime := <-MyTimer.C //定时满,系统自动写入时长
fmt.Println("now time:",nowTime)
}
time.After()定时:指定定时的时长,定时到达后,系统会自动向定时器的成员写入系统当前时间。返回可读的chan。读取后获得系统写入时间。
三种定时方法
在这里插入代码片
//3种定时方法,
func main(){
//1.Sleep
time.Sleep(time.Second)
//2.Timer.C
MyTimer := time.NewTimer(time.Second*3) //创建定时器,指定定时时长
nowTime := <-MyTimer.C //定时满,系统自动写入时长
fmt.Println("now time:",nowTime)
//3.time。After
nowTIme2 := <-time.After(time.Second*2)
fmt.Println("当下时间:",nowTIme2)
}
总结:Sleep、NewTimer、After----time包
定时器的 停止、重置:
1)创建定时器myTimer := time.NewTImer(2*time.Second)
2) 停止定时器 myTimer.Stop() — 将定时器归零。 <-myTimer.C会阻塞
3)重置 :myTimer.Reset(time.Second)
周期定时:
type Ticker struct{
C <-chan Time
r runtimeTimer
}
1 创建周期定时器 myTicker := time.NewTicker(time.Second)
定时时长到达后,系统会自动向Ticker的C中写入系统当前时间,并且每隔一个定长时长后,循环写入系统当前时间。
2.在子go程中循环读取C,获取系统写入时间

本文详细介绍了Go语言中通道Channel的各种用法,包括无缓冲和有缓冲的Channel,同步与异步操作,关闭Channel的规则,单向Channel的创建与转换,以及定时器的使用。通过实例展示了Channel在并发编程中的重要作用。
5万+

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



