如何使用 channel

简介: 如何使用 Channel例子来自于Concurrency is not parallelismGoogle Search: A fake frameworkv1.0var ( Web = fakeSearch("web") Image = fakeSearch("image"...

如何使用 Channel

例子来自于Concurrency is not parallelism

Google Search: A fake framework

v1.0

var (
    Web = fakeSearch("web")
    Image = fakeSearch("image")
    Video = fakeSearch("video")
)

type Search func(query string) Result

func fakeSearch(kind string) Search {
        return func(query string) Result {
              time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
              return Result(fmt.Sprintf("%s result for %q\n", kind, query))
        }
}
func main() {
    rand.Seed(time.Now().UnixNano())
    start := time.Now()
    results := Google("golang")
    elapsed := time.Since(start)
    fmt.Println(results)
    fmt.Println(elapsed)
}

关键函数

func Google(query string) (results []Result) {
    results = append(results, Web(query))
    results = append(results, Image(query))
    results = append(results, Video(query))
    return
}

Google 2.0

每个 search, 独立并发.
No locks. No condition variables. No callbacks.

func Google(query string) (results []Result) {
    c := make(chan Result)
    go func() { c <- Web(query) } ()
    go func() { c <- Image(query) } ()
    go func() { c <- Video(query) } ()

    for i := 0; i < 3; i++ {
        result := <-c
        results = append(results, result)
    }
    return
}

Google 2.1

如果某个服务比较慢,怎么办?
No locks. No condition variables. No callbacks.

func Google(query string) (results []Result) {
    c := make(chan Result)
    go func() { c <- Web(query) } ()
    go func() { c <- Image(query) } ()
    go func() { c <- Video(query) } ()

    timeout := time.After(80 * time.Millisecond)
    for i := 0; i < 3; i++ {
        select {
        case result := <-c:
            results = append(results, result)
        case <-timeout:
            fmt.Println("timed out")
            return
        }
    }
    return
}

Google 3.0 Avoid timeout

No locks. No condition variables. No callbacks.

func First(query string, replicas ...Search) Result {
    c := make(chan Result)
    searchReplica := func(i int) { c <- replicas[i](query) }
    for i := range replicas {
        go searchReplica(i)
    }
    return <-c
}
func Google(query string) (results []Result) {
   c := make(chan Result)
    go func() { c <- First(query, Web1, Web2) } ()
    go func() { c <- First(query, Image1, Image2) } ()
    go func() { c <- First(query, Video1, Video2) } ()
    timeout := time.After(80 * time.Millisecond)
    for i := 0; i < 3; i++ {
        select {
        case result := <-c:
            results = append(results, result)
        case <-timeout:
            fmt.Println("timed out")
            return
        }
    }
    return
}

Google 3.1

上面的例子看起来挺完美,但是存在一个严重的内存泄漏,不知道你看出来没有.
First 中的 searchReplica调用,除了第一个会成功返回以外,其他都不会返回.因为堵塞在 c 上面,从而导致了内存泄漏.
改进也很简单

func First(query string, replicas ...Search) Result {
    c := make(chan Result,len(replicas)) //看似多分配了资源,但是很快就会收回
    searchReplica := func(i int) { c <- replicas[i](query) }
    for i := range replicas {
        go searchReplica(i)
    }
    return <-c
}

经过简单的替换,通过 Go 的并发模型,将一个慢的,顺序执行的,故障敏感的程序改造为了一个快速的,并发的,有冗余的,健壮的程序.

完整的 google 3.1

var (
    Web1 = fakeSearch("web")
    Web2 = fakeSearch("web")
    Image1 = fakeSearch("image")
    Image2 = fakeSearch("image")
    Video1 = fakeSearch("video")
    Video2 = fakeSearch("video")
)

type Search func(query string) Result

func fakeSearch(kind string) Search {
        return func(query string) Result {
              time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
              return Result(fmt.Sprintf("%s result for %q\n", kind, query))
        }
}
func main() {
    rand.Seed(time.Now().UnixNano())
    start := time.Now()
    results := Google("golang")
    elapsed := time.Since(start)
    fmt.Println(results)
    fmt.Println(elapsed)
}

func First(query string, replicas ...Search) Result {
    c := make(chan Result,len(replicas)) 
    searchReplica := func(i int) { c <- replicas[i](query) }
    for i := range replicas {
        go searchReplica(i)
    }
    return <-c
}
func Google(query string) (results []Result) {
   c := make(chan Result)
    go func() { c <- First(query, Web1, Web2) } ()
    go func() { c <- First(query, Image1, Image2) } ()
    go func() { c <- First(query, Video1, Video2) } ()
    timeout := time.After(80 * time.Millisecond)
    for i := 0; i < 3; i++ {
        select {
        case result := <-c:
            results = append(results, result)
        case <-timeout:
            fmt.Println("timed out")
            return
        }
    }
    return
}
目录
相关文章
|
6月前
|
人工智能 弹性计算 监控
从会用到精通!OpenClaw 全平台部署+Anthropic工程师9条实战心法+Skill设计黄金法则+大模型配置完全实战分享
2026年,AI智能体的核心竞争力已经从“模型强弱”转向**Skill工程能力**。Anthropic内部工程师经过数百个Skill实战验证,总结出一套真正落地、避坑、可复用的Skill设计心法——Skill不是单个Markdown文件,而是完整文件夹体系;不是简单指令,而是可进化、可验证、可自动化、可记忆的生产级单元。这套经验直接适用于OpenClaw(Clawdbot),能让你的智能体从“能用”瞬间升级为“生产级稳定运行”。
735 1
|
7月前
|
存储 弹性计算 安全
阿里云99元和199元特价云服务器怎么买更划算?专属云产品组合套餐优惠分享
阿里云推出99元与199元特价云服务器套餐,含建站礼包(域名+ECS+建站工具),新购续费同价,支持5个网站/APP备案。加99元解锁弹性数据库,搭配OSS享高效存储保障。此外,提供优选镜像一键部署,无忧数据备份SCU低至3折。多场景组合套餐,如企业上云、H5建站等,满足多样化需求。用户可根据实际需求选择,获取最大优惠与优质服务。
514 4
阿里云99元和199元特价云服务器怎么买更划算?专属云产品组合套餐优惠分享
|
IDE Shell 网络安全
Visual Studio 2022 git error Unable to negotiate with xx.xxx.xxxx port 22: no matching host key type found. Their offer: ssh-rsa
Visual Studio 2022 git error Unable to negotiate with xx.xxx.xxxx port 22: no matching host key type found. Their offer: ssh-rsa
1132 0
Visual Studio 2022 git error Unable to negotiate with xx.xxx.xxxx port 22: no matching host key type found. Their offer: ssh-rsa
|
8月前
|
弹性计算 人工智能 数据挖掘
阿里云服务器租用一年费用详解:2026年最新版活动价格与优惠购买指导
2026年阿里云服务器租用价格调整后,提供多样化配置选择以满足不同用户需求。价格受实例规格、带宽、系统盘容量、购买时长及优惠活动影响。轻量应用服务器2核2G配置年付仅38元,99元和199元云服务器为中小企业和开发者提供低价长效选择。此外,还有计算型、通用型、内存型等多种实例规格。阿里云丰富的实例类型和优惠活动使用户能根据自身需求和预算,灵活选择高性价比的云服务器配置,有效降低上云成本。
669 3
|
11月前
|
监控 安全 Nacos
《服务治理》配置中心:微服务架构的"中央控制台"
配置中心是微服务架构的核心组件,实现配置集中化、动态更新、环境隔离与版本控制。通过Nacos等工具,支持实时推送、加密管理、灰度发布及多环境治理,提升系统灵活性与可靠性,是分布式系统不可或缺的基础设施。
|
5月前
|
传感器 人工智能 安全
Claude 开始进桌面之后,AI 系统的测试边界是不是又变了?
AI正从“问答工具”跃升为“操作执行者”,深度融入桌面、办公与企业系统。对测试而言,边界已从结果验证扩展至过程、环境、风险与长期稳定性验证——传统功能测试失效,亟需构建覆盖任务链路、异常恢复、安全可控的AI专属测试框架。
|
10月前
|
编解码 语音技术 数据安全/隐私保护
企业微信协议语音链路的技术实现
企业微信移动端语音采用0x0602指令,通过长连接传输Silk压缩流,降低30%首包延迟。协议含固定帧头与TLV结构,支持AES加密与实时解码,网关可透明转码对接ASR系统,整体延迟约8ms,CPU占用低。
524 0
|
7月前
|
运维 Linux 应用服务中间件
Linux sort命令实战教程
本文详解Linux `sort`命令:从基础排序、数字/反向/去重/忽略大小写等常用参数,到按字段(-k)、分隔符(-t)、月份(-M)、人类可读大小(-h)等进阶用法,并附日志、CSV、文件大小等实战案例。通俗易懂,示例可直接运行,新手也能快速掌握。
|
7月前
|
人工智能 监控 物联网
大数据微调GPU选择
本文详解大模型微调的GPU选型逻辑:显存是能否运行的门槛(7B模型需8–16GB,33B需24–48GB),算力影响速度,NVIDIA生态最成熟。按预算分三档推荐显卡与实操方案,并教你看显存利用率、训练速度和成本效益,助新手少走弯路、高效入门。(239字)
|
8月前
|
人工智能 自然语言处理 搜索推荐
2026年适合中小企业的智能客服系统推荐,轻量化部署+灵活计费
2026年,中小企业智能客服需求聚焦“轻量化、低成本、高适配”。瓴羊Quick Service凭借开箱即用的电商深度集成、93%+意图识别准确率的大模型引擎,及999元/月起的灵活SaaS计费,助力企业降本75%、响应提速至2.1秒,成为数字化转型优选。(239字)