unbuffered and buffered channel in golang

心情记录:最近因为工作原因开始接触golang,过年前扫了一遍。以前总是不那么认真去记一些东西,总想着用的时候在去搜索查询,但是这样总是不熟练。
今年想努力向一个优秀的程序员/算法工程师靠拢,所以有空就记录一下平时看到的技术点吧。

总述:

Effective Go 里面指出:

If the channel is unbuffered, the sender blocks until the receiver
has received the value. If the channel has a buffer, the sender blocks
only until the value has been copied to the buffer; if the buffer is
full, this means waiting until some receiver has retrieved a value.
无缓冲通道即发送者一直阻塞直到接收者收到value;
缓冲通道即发送者只需阻塞直到value被拷贝到缓冲区,若缓冲区满了,则等待直到某个接收者收到一个值。

以下例子来自参考1

1. 无缓冲通道

An unbuffered channel is a channel that needs a receiver as soon as a message is emitted to the channel.
无缓冲通道是消息一旦发送到该通道就需要接收者的通道。

package main

import (
	"sync"
	"time"
)

func main() {
	c := make(chan string)

	var wg sync.WaitGroup
	wg.Add(2)

	go func() {
		defer wg.Done()
		c <- `foo`
	}()

	go func() {
		defer wg.Done()

		time.Sleep(time.Second * 1)
		println(`Message: `+ <-c)
	}()

	wg.Wait()
}

代码步骤解释(自己翻译的不准确):

  1. 创建一个空接收者和发送者列表的通道;
  2. line16:第一个goroutine发送值“foo”到通道 c
  3. 通道c需要pool中的sudog结构体来代表一个sender,这个结构体将代表这个goroutine和值foo;
  4. 现在将sender入队到sendq中;
  5. 该goroutine的状态变更为waiting,变更原因为“chan send”;
  6. line 23:第二个goroutine将从通道c中读取消息;
  7. 通道使得sendqlist出列来获得一个sender,即步骤3中说明的那个结构体;
  8. 该通道将用memmove函数拷贝sender发送的值,打包到sudog结构体中,给我们的变量去读取通道;
  9. 至此,步骤5中中断的goroutine现在重新开始,释放步骤3中的sudog

2. 缓冲通道

以下实例代码在刚才的基础上简单修改c的buffer为2:


package main

import (
	"sync"
	"time"
)

func main() {
	c := make(chan string, 2)

	var wg sync.WaitGroup
	wg.Add(2)

	go func() {
		defer wg.Done()

		c <- `foo`
		c <- `bar`
	}()

	go func() {
		defer wg.Done()

		time.Sleep(time.Second * 1)
		println(`Message: `+ <-c)
		println(`Message: `+ <-c)
	}()

	wg.Wait()
}

Goroutines spend 9ms blocked in synchronization waiting for a value from the unbuffered channel while a 50-sized buffer only wait for 1.9ms.
We do now have a confirmation of our previous doubts. The size of the buffer can play an important role in our application performances.

参考2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值