golang的channel什么时候会阻塞?什么时候会恢复?

在 Go 语言中,channel 的发送和接收操作会根据其缓冲区的状态而阻塞或恢复。以下是详细说明:

1. 无缓冲 channel

  • 发送操作

    • 阻塞:发送数据时会阻塞,直到有另一个 goroutine 从该 channel 接收数据。
  • 接收操作

    • 阻塞:接收数据时会阻塞,直到有另一个 goroutine 向该 channel 发送数据。

2. 有缓冲 channel

  • 发送操作

    • 阻塞:当缓冲区已满时,发送操作会阻塞,直到有空间可以发送数据。
    • 恢复:当接收操作释放了空间(即接收数据),发送操作会恢复执行。
  • 接收操作

    • 阻塞:当缓冲区为空时,接收操作会阻塞,直到有数据可以接收。
    • 恢复:当发送操作添加了数据,接收操作会恢复执行。

示例代码

以下是一个示例,展示无缓冲和有缓冲 channel 的阻塞和恢复行为:

package main

import (
	"fmt"
	"time"
)

func main() {
	// 无缓冲 channel 示例
	ch1 := make(chan int)

	go func() {
		ch1 <- 1 // 发送数据,阻塞直到接收
		fmt.Println("Sent 1")
	}()

	// 主 goroutine 等待一秒再接收
	time.Sleep(1 * time.Second)
	fmt.Println("Received:", <-ch1) // 接收数据,解除阻塞

	// 有缓冲 channel 示例
	ch2 := make(chan int, 2) // 缓冲区大小为 2

	ch2 <- 1 // 不会阻塞
	ch2 <- 2 // 也不会阻塞

	go func() {
		ch2 <- 3 // 这里会阻塞,直到有接收
		fmt.Println("Sent 3")
	}()

	fmt.Println("Received from buffered channel:", <-ch2) // 接收,解除阻塞
	fmt.Println("Received from buffered channel:", <-ch2) // 继续接收
	time.Sleep(1 * time.Second) // 确保 goroutine 完成
}

总结

  • 无缓冲 channel:发送和接收操作会相互阻塞,直到对方准备好。
  • 有缓冲 channel:发送操作在缓冲区未满时不会阻塞;接收操作在缓冲区为空时会阻塞。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值