Go并发控制Channel使用场景分析

1. 前言

channel一个类型管道,通过它可以在goroutine之间发送和接收消息。它是Golang在语言层面提供的goroutine间的通信方式。

Channel是Go中的一个核心类型,你可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication)。

它的操作符是箭头 <- 。

我们考虑这么一种场景,协程A执行过程中需要创建子协程A1、A2、A3…An,协程A创建完子协程后就等待子协程退出。

针对这种场景,GO提供了三种解决方案:

  • Channel: 使用channel控制子协程
  • WaitGroup : 使用信号量机制控制子协程
  • Context: 使用上下文控制子协程

三种方案各有优劣,比如Channel优点是实现简单,清晰易懂,WaitGroup优点是子协程个数动态可调整,Context优点是对子协程派生出来的孙子协程的控制。
缺点是相对而言的,要结合实例应用场景进行选择。

channel一般用于协程之间的通信,channel也可以用于并发控制。比如主协程启动N个子协程,主协程等待所有子协程退出后再继续后续流程,这种场景下channel也可轻易实现。

2. 使用channel控制子协程

2.1 使用场景

package main

import (
    "time"
    "fmt"
)

func Process(ch chan int) {
    //Do some work...
    time.Sleep(time.Second)

    ch <- 1 //管道中写入一个元素表示当前协程已结束
}

func main() {
    channels := make([]chan int, 10) //创建一个10个元素的切片,元素类型为channel

    for i:= 0; i < 10; i++ {
        channels[i] = make(chan int) //切片中放入一个channel
        go Process(channels[i])      //启动协程,传一个管道用于通信
    }

    for i, ch := range channels {  //遍历切片,等待子协程结束
        <-ch
        fmt.Println("Routine ", i, " quit!")
    }
}

上面程序通过创建N个channel来管理N个协程,每个协程都有一个channel用于跟父协程通信,父协程创建完所有协程后等待所有协程结束。

这个例子中,父协程仅仅是等待子协程结束,其实父协程也可以向管道中写入数据通知子协程结束,这时子协程需要定期地探测管道中是否有消息出现。

2.2 总结

使用channel来控制子协程的优点是实现简单,缺点是当需要大量创建协程时就需要有相同数量的channel,而且对于子协程继续派生出来的协程不方便控制。

到此这篇关于Go并发控制Channel使用场景分析的文章就介绍到这了,更多相关Go并发控制Channel内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Go并发控制WaitGroup的使用场景分析

    1. 前言 上一篇介绍了 Go并发控制--Channel 使用channel来控制子协程的优点是实现简单,缺点是当需要大量创建协程时就需要有相同数量的channel,而且对于子协程继续派生出来的协程不方便控制. 2. 使用WaitGroup控制 WaitGroup,可理解为Wait-Goroutine-Group,即等待一组goroutine结束.比如某个goroutine需要等待其他几个goroutine全部完成,那么使用WaitGroup可以轻松实现. 2.1 使用场景 下面程序展示了一个g

  • Go 并发控制context实现原理剖析(小结)

    1. 前言 Golang context是Golang应用开发常用的并发控制技术,它与WaitGroup最大的不同点是context对于派生goroutine有更强的控制力,它可以控制多级的goroutine. context翻译成中文是"上下文",即它可以控制一组呈树状结构的goroutine,每个goroutine拥有相同的上下文. 典型的使用场景如下图所示: 上图中由于goroutine派生出子goroutine,而子goroutine又继续派生新的goroutine,这种情况下

  • Golang 实现分片读取http超大文件流和并发控制

    分片读取http超大文件流 Golang中的HTTP发送get请求,在获取内容有两种情况. Golang发送http get请求方式 resp, err := http.Get(sendUrl) if err != nil { fmt.Println("出错", err) return } 第一种方式是直接全部读取出来,这种方式在小数据量的时候很方便. body变量直接全部接收resp响应内容 body, err2 := ioutil.ReadAll(resp.Body) 第二种方式,

  • Django Channels 实现点对点实时聊天和消息推送功能

    简介在很多实际的项目开发中,我们需要实现很多实时功能:而在这篇文章中,我们就利用django channels简单地实现了点对点聊天和消息推送功能. 手边有一个项目需要用到后台消息推送和用户之间一对一在线聊天的功能.例如用户A评论了用户B的帖子,这时候用户B就应该收到一条通知,显示自己的帖子被评论了.这个功能可以由最基本的刷新页面后访问数据库来完成,但是这样会增加对后台服务器的压力,同时如果是手机客户端的话,也会造成流量的损失.于是,我们考虑使用websocket建立一个连接来完成这个功能. 但

  • 基于django channel实现websocket的聊天室的方法示例

    websocket 网易聊天室? ​ web微信? ​ 直播? 假如你工作以后,你的老板让你来开发一个内部的微信程序,你需要怎么办?我们先来分析一下里面的技术难点 消息的实时性? 实现群聊 现在有这样一个需求,老板给到你了,关乎你是否能转正?你要怎么做? 我们先说消息的实时性,按照我们目前的想法是我需要用http协议来做,那么http协议怎么来做那? 是不是要一直去访问我们的服务器,问服务器有没有人给我发消息,有没有人给我发消息?那么大家认为我多长时间去访问一次服务比较合适那? 1分钟1次?1分

  • Go并发控制Channel使用场景分析

    1. 前言 channel一个类型管道,通过它可以在goroutine之间发送和接收消息.它是Golang在语言层面提供的goroutine间的通信方式. Channel是Go中的一个核心类型,你可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication). 它的操作符是箭头 <- . 我们考虑这么一种场景,协程A执行过程中需要创建子协程A1.A2.A3-An,协程A创建完子协程后就等待子协程退出. 针对这种场景,GO提供了三种解决方案: Channel:

  • golang 中的 nil的场景分析

    源码中的 nil 是这样定义的 // nil is a predeclared identifier representing the zero value for a // pointer, channel, func, interface, map, or slice type. var nil Type // Type must be a pointer, channel, func, interface, map, or slice type 所以 nil 可以理解为这些类型的零值,声明

  • 关于SQL数据库 msdb.dbo.sp_send_dbmail 函数发送邮件的场景分析

    在推行系统中,时不时会有用户提出希望系统能自动推送邮件,由于手头的工具和能力有限,不少需求都借助于sql server的邮件触发来实现. 步骤: 1.配置邮箱.步骤略,网上有不少帖子说明,手工直接在管理-数据库邮件配置即可.配置完成后可以右键测试邮箱是否正常工作. 2.制作发送邮件脚本 3.sql server 代理定义周期计划 邮件脚本编写: 场景一:业务部门希望可以每周提供一次样品库存,即将sql查询的结果以附件的方式发给指定的人员. EXEC msdb.dbo.sp_send_dbmail

  • Python 私有属性和私有方法应用场景分析

    类的私有属性和方法 Python是个开放的语言,默认情况下所有的属性和方法都是公开的 或者叫公有方法,不像C++和 Java中有明确的public,private 关键字来区分私有公有. Python默认的成员函数和成员变量都是公开的,类的私有属性指只有在类的内部使用的属性或方法,表现形式为以"__" 属性名或方法名以双下划线开头. class Test(object): __count = 0 # 私有属性 __count def get_count(self): return se

  • Webstorm解除版本控制的场景分析

    一.适用场景 有时我们想要复制一份远端check下来的代码在本地进行自由改动,但是如果还在svn或者git的版本控制下就会出现很多不必要的麻烦. 比如很多文件会是红色,新建文件的时候会很慢就像这样 二.解除方式 如果我们仅仅想简单的解除版本控制,推荐如下方式: 找到你项目所在文件夹,里面有个.idea文件夹 打开文件夹,有一个vcs.xml,这就是webstorm配置版本控制工具的配置文件 对其进行编辑 将 <mapping directory="$PROJECT_DIR$" v

  • vue router返回到指定的路由的场景分析

    项目场景: 项目场景:示例:A(商品详情)--B(商品购买页面)-C(支付成功页面)--D(订单页面) 问题描述: 提示:这里描述项目中遇到的问题: 如果我们不做控制的话,安卓按照浏览器返回机制,依次从D-C-B-A这样子,这样子会有一定的bug,测试那边也是说不过去啊,原本想利用beforeRouteLeave这个来操作进行更改跳转,发现还是有点问题最后还是用beforeRouteEnter来操作了,先放上两个的区别吧: 这里先介绍一下导航守卫 > beforeRouteEnter 离开路由之

  • Git提交代码错了吃后悔药的几种常用办法(场景分析)

    1. 前言 写代码都会犯错误,不小心提交了一个错误我该怎么办?提交的描述信息我该怎么办?如果你也遇到这个问题,那么今天胖哥分享的这篇文章将非常适合你. 2. Commit 错了怎么办 放心都是有后悔药吃的,我们来看看. 场景一 假如你git commit了一堆代码,但是你发现本次Commit的描述信息有点随意,你可以这样: git commit --amend -m"新的提交消息" 场景二 你本来打算Commit五个文件,但是由于疏忽你Commit了四个.当然你可以再Commit一次来

  • 基于Vue3.0开发轻量级手机端弹框组件V3Popup的场景分析

    之前有分享一个vue2.x移动端弹框组件,今天给大家带来的是Vue3实现自定义弹框组件. V3Popup 基于vue3.x实现的移动端弹出框组件,集合msg.alert.dialog.modal.actionSheet.toast等多种效果.支持20+种自定义参数配置,旨在通过极简的布局.精简的调用方式解决多样化的弹框场景. v3popup 在开发之初参考借鉴了Vant3.ElementPlus等组件化思想.并且功能效果和之前vue2.0保持一致. ◆ 快速引入 在main.js中全局引入v3p

  • JDK1.8中的ConcurrentHashMap使用及场景分析

    ConcurrentHashMap 的初步使用及场景: ConcurrentHashMap 是 J.U.C 包里面提供的一个线程安全并且高效的 HashMap,所以ConcurrentHashMap 在并发编程的场景中使用的频率比较高,那么我们就从ConcurrentHashMap 的使用上以及源码层面来分析 ConcurrentHashMap 到底是如何实现安全性的 api 使用: ConcurrentHashMap 是 Map 的派生类,所以 api 基本和 Hashmap 是类似,主要就是

随机推荐