0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用channel控制协程数量

马哥Linux运维 来源:稀土掘金技术社区 作者:六号积极分子 2022-09-19 15:06 次阅读

协程

goroutine 是轻量级线程,调度由 Go 运行时进行管理的。Go 语言的并发控制主要使用关键字 go 开启协程 goroutine。Go 协程(Goroutine)之间通过信道(channel)进行通信,简单的说就是多个协程之间通信的管道。信道可以防止多个协程访问共享内存时发生资源争抢的问题。语法格式:

// 普通函数创建 goroutinego 函数名(参数列表)
//匿名函数创建 goroutinego func(参数列表){    //函数体}(调用参数列表)

		

协程可以开启多少个?是否有限制呢?

func testRoutine() {    var wg sync.WaitGroup    for i := 0; i < math.MaxInt32; i++ {        wg.Add(1)        go func(i int) {            defer wg.Done()            fmt.Printf("并发数量:%d/n", i)            time.Sleep(time.Second)        }(i)    }    wg.Wait()}

		

以上代码开启了 math.MaxInt32个协程的并发,执行后可以看到结果直接 panic:“panic: too many concurrent operations on a single file or socket (max 1048575)”。整个并发操作超出了系统最大值。

控制协程数量

sync 同步机制

使用 sync.WaitGroup 启动指定数量的协程 goroutine。

func testRoutine() {    var wg = sync.WaitGroup{}
    taskCount := 5 // 指定并发数量    for i := 0; i < taskCount; i++ {        wg.Add(1)        go func(i int) {            fmt.Println("go func ", i)            wg.Done()        }(i)    }    wg.Wait()}

		

如果 taskcount 设置的很大超出了限制的,则其还是没有控制到并发数量。可以优化下设计,类似池的设计思想,通过允许最大连接数控制量,当超出了数量就需要等待释放,有空闲的连接的时候才可以继续执行。

func testRoutine() {    task_chan := make(chan bool, 3) //100 为 channel长度    wg := sync.WaitGroup{}    defer close(task_chan)    for i := 0; i < math.MaxInt; i++ {        wg.Add(1)        fmt.Println("go func ", i)        task_chan <- true        go func() {                <-task_chan                defer wg.Done()        }()    }
    wg.Wait()}

		

  • 创建缓冲区大小为 3 的 channel,在没有被接收的情况下,至多发送 3 个消息则被阻塞。通过 channel 控制每次并发的数量。
  • 开启协程前,设置 task_chan <- true,若缓存区满了则阻塞
  • 协程任务执行完成后就释放缓冲区
  • 等待所有的并发都处理结束后则函数结束。其实可以不使用 sync.WaitGroup。因使用 channel 控制并发处理的任务数量可以不用使用等待并发处理结束。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Channel
    +关注

    关注

    0

    文章

    31

    浏览量

    11845
  • 线程
    +关注

    关注

    0

    文章

    505

    浏览量

    19744
  • go语言
    +关注

    关注

    1

    文章

    158

    浏览量

    9082

原文标题:使用 channel 控制并发数量

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    谈谈的那些事儿

    随着异步编程的发展以及各种并发框架的普及,作为一种异步编程规范在各类语言中地位逐步提高。我们不单单会在自己的程序中使用,各类框架如fastapi,aiohttp等也都是基于异步
    的头像 发表于 01-26 11:36 1162次阅读
    谈谈<b class='flag-5'>协</b><b class='flag-5'>程</b>的那些事儿

    和线程有什么区别

    和线程的区别和线程的共同目的之一是实现系统资源的上下文调用,不过它们的实现层级不同;线程(Thraed)是比进程小一级的的运行单位,多线程实现系统资源上下文调用,是编程语言交付
    发表于 12-10 06:23

    Python中的多核CPU共享数据之详解

    又称微线程,coroutne,是一种用户态的轻量级线程。通俗点讲就是周末我在家里休息,假如我先洗漱,再煮饭,再下载电影看会很慢,用了
    的头像 发表于 12-07 10:23 6685次阅读
    Python中的多核CPU共享数据之<b class='flag-5'>协</b><b class='flag-5'>程</b>详解

    关于C++ 20最全面详解

    花了一两周的时间后,我想写写 C++20 的基本用法,因为 C++ 的让我感到很奇怪,写一个
    的头像 发表于 04-12 11:10 1.3w次阅读
    关于C++ 20<b class='flag-5'>协</b><b class='flag-5'>程</b>最全面详解

    Python后端项目的是什么

    最近公司 Python 后端项目进行重构,整个后端逻辑基本都变更为采用“异步”的方式实现。看着满屏幕经过 async await(在 Python 中的实现)修饰的代码,我顿时
    的头像 发表于 09-23 14:38 1363次阅读

    Python与JavaScript的对比及经验技巧

    前言以前没怎么接触前端,对 JavaScript 的异步操作不了解,现在有了点了解。一查发现 Python 和 JavaScript 的发展史简直就是一毛一样!这里大致做下横向对比和总结,便于
    的头像 发表于 10-20 14:30 1973次阅读

    通过例子由浅入深的理解yield

    send:send() 方法致使程前进到下一个yield 语句,另外,生成器可以作为使用
    的头像 发表于 08-23 11:12 2066次阅读

    详解Linux线程、线程与异步编程、与异步

    不是系统级线程,很多时候被称为“轻量级线程”、“微线程”、“纤(fiber)”等。简单来说可以认为
    的头像 发表于 03-16 15:49 1034次阅读

    的概念及的挂起函数介绍

    是一种轻量级的线程,它可以在单个线程中实现并发执行。与线程不同,不需要操作系统的上下文切换,因此可以更高效地使用系统资源。Kotlin
    的头像 发表于 04-19 10:20 930次阅读

    Kotlin实战进阶之筑基篇3

    的概念在1958年就开始出现(比线程还早), 目前很多语言开始原生支, Java 没有原生但是大型公司都自己或者使用第三方库来支持
    的头像 发表于 05-30 16:26 737次阅读

    FreeRTOS任务与介绍

    FreeRTOS 中应用既可以使用任务,也可以使用(Co-Routine),或者两者混合使用。但是任务和协使用不同的API函数,因此不能通过队列(或信号量)将数据从任务发送给
    的头像 发表于 09-28 11:02 1035次阅读

    的作用、结构及原理

    本文介绍了的作用、结构、原理,并使用C++和汇编实现了64位系统下的池。文章内容避免了
    的头像 发表于 11-08 16:39 1204次阅读
    <b class='flag-5'>协</b><b class='flag-5'>程</b>的作用、结构及原理

    C/C++编程的相关概念和技巧

    一、引言 的定义和背景 (Coroutine),又称为微线程或者轻量级线程,是一种用户态的、可在单个线程中并发执行的程序组件。
    的头像 发表于 11-09 11:34 856次阅读

    的实现与原理

    前言 这个概念很久了,好多程序员是实现过这个组件的,网上关于的文章,博客,论坛都是汗牛充栋,在知乎,github上面也有很多大牛写了关于
    的头像 发表于 11-10 10:57 472次阅读

    Linux线程、线程与异步编程、与异步介绍

    不是系统级线程,很多时候被称为“轻量级线程”、“微线程”、“纤(fiber)”等。简单来说可以认为
    的头像 发表于 11-11 11:35 1260次阅读
    Linux线程、线程与异步编程、<b class='flag-5'>协</b><b class='flag-5'>程</b>与异步介绍