Go中的channel是同步还是异步

Go语言中的channel可以是异步也可以是同步,这取决与它是否是一个缓冲的channel

同步channel

无缓冲的channel默认是同步的channel类型,即创建时没有执行缓冲大小。当数据被发送到无缓冲的channel中时,发送者会阻塞直到接受者收到数据。同样,当从无缓冲的channel中接收数据的时候,接受者会阻塞直到发送者发送数据。这种机制允许两个goroutine进行同步的通信。

go 复制代码
package main

import (
    "fmt"
)

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

    go func() {
        ch <- 42 // 发送操作会阻塞,直到main goroutine执行接收操作
    }()

    fmt.Println(<-ch) // 接收操作,会阻塞直到有值发送到channel
}

异步的channel

有缓冲的channel是异步的,它拥有一个缓冲队列,创建channel的时候指定队列的大小。发送者向有缓冲的channel发送数据的时候,如果缓冲区未满,则发送就不会阻塞,否则发送者同样会阻塞直到有接受者接收到数据。同样,接收者从有缓冲区的channel接收数据时,如果缓冲中有数据,则接收就不会阻塞,否则接收者会阻塞直到缓冲区有发送者发送数据。

go 复制代码
package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int, 2) // 创建一个缓冲区大小为2的channel

    // 向channel发送两个数据
    ch <- 1
    ch <- 2

    go func() {
        // 延迟1秒后发送第三个数据,此时发送会阻塞,因为缓冲区已满
        time.Sleep(1 * time.Second)
        ch <- 3
        fmt.Println("Sent 3")
    }()

    // 主goroutine接收数据
    fmt.Println(<-ch) // 接收第一个数据,输出1
    fmt.Println(<-ch) // 接收第二个数据,输出2

    // 第三个接收操作会阻塞,直到发送者发送第三个数据
    fmt.Println(<-ch) // 接收第三个数据,输出3
}

最后给大家推荐一个LinuxC/C++高级架构系统教程的学习资源与课程,可以帮助你有方向、更细致地学习C/C++后端开发,具体内容请见 https://xxetb.xetslk.com/s/1o04uB

相关推荐
大橘喵喵重4 分钟前
FastAPI 实现国际化(i18n)和多语言支持的完整方案
后端
少莫千华5 分钟前
【Web API】RESTful API接口规范
前端·后端·json·api·restful·rest
用户2345267009826 分钟前
AI会不会悄悄把漏洞甚至后门写进你的代码里
后端·ai编程
实习生小黄8 分钟前
NestJS 调试方案
后端·nestjs
嘻哈baby11 分钟前
rsync文件同步:从备份到迁移的瑞士军刀
后端
Java水解15 分钟前
Spring Boot Starter自定义开发 构建企业级组件库
spring boot·后端
用户6174332731016 分钟前
访问Windows共享目录
后端
掘金酱17 分钟前
2025年度稀土掘金影响力榜单发布!
前端·人工智能·后端
程序员侠客行22 分钟前
Mybatis二级缓存实现详解
java·数据库·后端·架构·mybatis
源码获取_wx:Fegn089522 分钟前
基于springboot + vue健康茶饮销售管理系统
java·vue.js·spring boot·后端·spring