二十八、channel的传递

目录

一、无缓冲channel单向传输

1、创建生产者与消费者模型

2、增加main方法

3、修改生产者与消费者

二、有缓冲channel异步传输

1、修改消费者

2、修改生产者

3、不修改main方法

4、修改main方法


一、无缓冲channel单向传输

1、创建生产者与消费者模型
func send(ch chan<- int) {
	for i := 0; i < 10; i++ {
		ch <- i
	}
}
func receive(ch <-chan int) {
	for data := range ch {
		fmt.Println(data)
	}
}

注意当符号<-在chan右边代表往channel里发送数据,在左边代表从channel里取数据

2、增加main方法
func main() {
	var wg sync.WaitGroup
	ch := make(chan int)
	wg.Add(1)
	go send(ch)
	go receive(ch, &wg)
	wg.Wait()
}

增加wait方法是为了等待并发结束,能看到最终结果

在receive函数参数中添加wg是因为当消费者每接收一次done一次

3、修改生产者与消费者

生产者:

func send(ch chan<- int) {
	for i := 0; i < 10; i++ {
		ch <- i
	}
	close(ch)
}

在其中增加了close方法,如果不增加则会发生死锁错误,意味着如果不进行关闭,消费者中wg.done就会一直阻塞,又导致wg.wait方法阻塞

消费者:

func receive(ch <-chan int, wg *sync.WaitGroup) {
	defer wg.Done()
	for data := range ch {
		fmt.Println("接收数据:", data)
	}
}

使用defer wg.done让消费者每消费一次执行计数器-1

最终运行结果:

接收数据: 0
接收数据: 1
接收数据: 2
接收数据: 3
接收数据: 4
接收数据: 5
接收数据: 6
接收数据: 7
接收数据: 8
接收数据: 9
 

二、有缓冲channel异步传输

1、修改消费者

给消费者增加处理时间

func receive(ch <-chan int, wg *sync.WaitGroup) {
	defer wg.Done()
	for data := range ch {
		time.Sleep(1 * time.Second)
		fmt.Println("接收数据:", data)
	}
}
2、修改生产者

给生产者增加发送完成数据提醒

func send(ch chan<- int) {
	for i := 0; i < 10; i++ {
		ch <- i
	}
	fmt.Println("发送完成数据")
	close(ch)
}
3、不修改main方法

最终输出结果:

接收数据: 0
接收数据: 1
接收数据: 2
接收数据: 3
接收数据: 4
接收数据: 5
接收数据: 6
接收数据: 7
接收数据: 8
发送完成数据
接收数据: 9
 

通过结果可以发现一直到沉默了9秒后才发送结束,效率不高

4、修改main方法

给main方法中channel增加缓冲

func main() {
	var wg sync.WaitGroup
	ch := make(chan int, 10)
	wg.Add(1)
	go send(ch)
	go receive(ch, &wg)
	wg.Wait()
}

最终结果:

发送完成数据
接收数据: 0
接收数据: 1
接收数据: 2
接收数据: 3
接收数据: 4
接收数据: 5
接收数据: 6
接收数据: 7
接收数据: 8
接收数据: 9
 

通过结果我们看到效率明显提高了,一执行就完成了数据的发送,达到了并行的效果,因为当给缓冲的时候数据可以直接写入channel而不用关心数据是否有人在读。简单来说就是有缓冲空间就可以直接写入,没有缓冲空间就必须一写一读的方式执行

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值