golang 的 buffered channel 及 unbuffered channel

本文通过两个示例深入探讨了Go语言中通道(channel)的两种类型:无缓冲通道与带缓冲通道的工作原理。文章展示了这两种通道如何影响发送者与接收者的阻塞行为,并解释了缓冲区大小如何影响数据的流动。

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

The channel is divided into two categories: unbuffered and buffered.

(1) Unbuffered channel
For unbuffered channel, the sender will block on the channel until the receiver receives the data from the channel, whilst the receiver will also block on the channel until sender sends data into the channel. Check the following example:

package main

import (
        "fmt"
        "time"
)

func main() {
        ch := make(chan int)

        go func(ch chan int) {
                fmt.Println("Func goroutine begins sending data")
                ch <- 1
                fmt.Println("Func goroutine ends sending data")
        }(ch)

        fmt.Println("Main goroutine sleeps 2 seconds")
        time.Sleep(time.Second * 2)

        fmt.Println("Main goroutine begins receiving data")
        d := <-ch
        fmt.Println("Main goroutine received data:", d)

        time.Sleep(time.Second)
}

The running result likes this:

Main goroutine sleeps 2 seconds
Func goroutine begins sending data
Main goroutine begins receiving data
Main goroutine received data: 1
Func goroutine ends sending data

After the main goroutine is launched, it will sleep immediately("Main goroutine sleeps 2 seconds" is printed), and this will cause main goroutine relinquishes the CPU to the func goroutine("Func goroutine begins sending data" is printed). But since the main goroutine is sleeping and can't receive data from the channel, so ch <- 1 operation in func goroutine can't complete until d := <- ch in main goroutine is executed(The final 3 logs are printed).

 

(2) Buffered channel
Compared with unbuffered counterpart, the sender of buffered channel will block when there is no empty slot of the channel, while the receiver will block on the channel when it is empty. Modify the above example:

package main

import (
        "fmt"
        "time"
)

func main() {
        ch := make(chan int, 2)

        go func(ch chan int) {
                for i := 1; i <= 5; i++ {
                        ch <- i
                        fmt.Println("Func goroutine sends data: ", i)
                }
                close(ch)
        }(ch)

        fmt.Println("Main goroutine sleeps 2 seconds")
        time.Sleep(time.Second * 2)

        fmt.Println("Main goroutine begins receiving data")
        for d := range ch {
                fmt.Println("Main goroutine received data:", d)
        }
}

The executing result is as follows:

Main goroutine sleeps 2 seconds
Func goroutine sends data:  1
Func goroutine sends data:  2
Main goroutine begins receiving data
Main goroutine received data: 1
Main goroutine received data: 2
Main goroutine received data: 3
Func goroutine sends data:  3
Func goroutine sends data:  4
Func goroutine sends data:  5
Main goroutine received data: 4
Main goroutine received data: 5

In this sample, since the channel has 2 slots, so the func goroutine will not block until it sends the third element.

P.S., "make(chan int, 0)" is equal to "make(chan int)", and it will create an unbuffered int channel too.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值