GO chan缓冲通道

非缓冲通道的工作方式是读协程在读取chan时,若读取不到会就会阻塞在那里,直到读取到数据为止。写入也是这样如果没有其它协程读取本次的写入,写入协程也同样会阻塞在这里等待。
这种方式明显降低程序运行的效率,如果能写与读互不阻塞是不是就会快很多呢? 可不可以相互约定一块空间,我把数据放在指定的地方,读取者也去指定的地方读取,这样我把数据放在那里后立刻就可以去做别的事情。
缓冲chan就可以做这件事情,上缓冲chan代码:

package main

import (
	"fmt"
	"time"
)

func worker1(in chan<- string)  {
	fmt.Printf("%d\n",1)
	in <- "我"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",2)
	in <- "是"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",3)
	in <- "c"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",4)
	in <- "h"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",5)
	in <- "a"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",6)
	in <- "n"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",7)

	time.Sleep(time.Second*5)
}

func worker2(out <-chan string)  {
	value := ""
	i:=0
	for  {
		value = <-out
		i++
		fmt.Printf("out %d -> %s\n",i,value)
		time.Sleep(time.Second*2)
	}
}

func main() {
	//创建缓冲chan
	ch := make(chan string,3)

	go worker1(ch)
	go worker2(ch)

	time.Sleep(10*time.Second)
}

运行结果:

1
out 1 -> 我
2
3
4
out 2 -> 是
5
6
out 3 -> c
7
out 4 -> h
out 5 -> a

分析:
创建缓冲大小为3的chan,预计缓冲区放满3个数据写入协程才会被阻塞。
为了让多协程代码尽量按照预计的路线运行,在代码关键地方加了time.Sleep,由于时间差的原因最多才会存满3个,是很有可能还没存满3个就被读取了。所以结果才会如上面那样

为了对比运行逻辑,再上一份非缓冲chan的程序,上代码:

package main

import (
	"fmt"
	"time"
)

func worker1(in chan<- string)  {
	fmt.Printf("%d\n",1)
	in <- "我"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",2)
	in <- "是"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",3)
	in <- "c"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",4)
	in <- "h"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",5)
	in <- "a"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",6)
	in <- "n"
	time.Sleep(time.Millisecond*500)
	fmt.Printf("%d\n",7)

	time.Sleep(time.Second*5)
}

func worker2(out <-chan string)  {
	value := ""
	i:=0
	for  {
		value = <-out
		i++
		fmt.Printf("out %d -> %s\n",i,value)
		time.Sleep(time.Second*2)
	}
}


func main() {
	ch := make(chan string,3)

	go worker1(ch)
	go worker2(ch)

	time.Sleep(10*time.Second)
}

运行结果:

1
out 1 -> 我
2
out 2 -> 是
3
out 3 -> c
4
out 4 -> h
5
out 5 -> a
6

分析:
很明显的可以看出,非缓冲chan是相互阻塞交替运行的。
另外还有一个细节是信息没有输出完,这是因为协程睡眠十秒后就退出来,在它退出的时候会强制退出其它协程。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值