go语言通道channel 的用法汇总

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要总结了在学习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,获取系统写入时间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赤狐先生

如果有一点点帮助,可以给点支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值