0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

使用channel控制協(xié)程數(shù)量

馬哥Linux運(yùn)維 ? 來源:稀土掘金技術(shù)社區(qū) ? 作者:六號積極分子 ? 2022-09-19 15:06 ? 次閱讀

協(xié)程

goroutine 是輕量級線程,調(diào)度由 Go 運(yùn)行時進(jìn)行管理的。Go 語言的并發(fā)控制主要使用關(guān)鍵字 go 開啟協(xié)程 goroutine。Go 協(xié)程(Goroutine)之間通過信道(channel)進(jìn)行通信,簡單的說就是多個協(xié)程之間通信的管道。信道可以防止多個協(xié)程訪問共享內(nèi)存時發(fā)生資源爭搶的問題。語法格式:

// 普通函數(shù)創(chuàng)建 goroutinego 函數(shù)名(參數(shù)列表)
//匿名函數(shù)創(chuàng)建 goroutinego func(參數(shù)列表){    //函數(shù)體}(調(diào)用參數(shù)列表)

		

協(xié)程可以開啟多少個?是否有限制呢?

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("并發(fā)數(shù)量:%d/n", i)            time.Sleep(time.Second)        }(i)    }    wg.Wait()}

		

以上代碼開啟了 math.MaxInt32個協(xié)程的并發(fā),執(zhí)行后可以看到結(jié)果直接 panic:“panic: too many concurrent operations on a single file or socket (max 1048575)”。整個并發(fā)操作超出了系統(tǒng)最大值。

控制協(xié)程數(shù)量

sync 同步機(jī)制

使用 sync.WaitGroup 啟動指定數(shù)量的協(xié)程 goroutine。

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

		

如果 taskcount 設(shè)置的很大超出了限制的,則其還是沒有控制到并發(fā)數(shù)量。可以優(yōu)化下設(shè)計,類似池的設(shè)計思想,通過允許最大連接數(shù)控制量,當(dāng)超出了數(shù)量就需要等待釋放,有空閑的連接的時候才可以繼續(xù)執(zhí)行。

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()}

		

  • 創(chuàng)建緩沖區(qū)大小為 3 的 channel,在沒有被接收的情況下,至多發(fā)送 3 個消息則被阻塞。通過 channel 控制每次并發(fā)的數(shù)量。
  • 開啟協(xié)程前,設(shè)置 task_chan <- true,若緩存區(qū)滿了則阻塞
  • 協(xié)程任務(wù)執(zhí)行完成后就釋放緩沖區(qū)
  • 等待所有的并發(fā)都處理結(jié)束后則函數(shù)結(jié)束。其實(shí)可以不使用 sync.WaitGroup。因使用 channel 控制并發(fā)處理的任務(wù)數(shù)量可以不用使用等待并發(fā)處理結(jié)束。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Channel
    +關(guān)注

    關(guān)注

    0

    文章

    31

    瀏覽量

    11749
  • 線程
    +關(guān)注

    關(guān)注

    0

    文章

    502

    瀏覽量

    19613
  • go語言
    +關(guān)注

    關(guān)注

    1

    文章

    156

    瀏覽量

    9004

原文標(biāo)題:使用 channel 控制并發(fā)數(shù)量

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    談?wù)?b class='flag-5'>協(xié)的那些事兒

    隨著異步編程的發(fā)展以及各種并發(fā)框架的普及,協(xié)作為一種異步編程規(guī)范在各類語言中地位逐步提高。我們不單單會在自己的程序中使用協(xié),各類框架如fastapi,aiohttp等也都是基于異步
    的頭像 發(fā)表于 01-26 11:36 ?1050次閱讀
    談?wù)?b class='flag-5'>協(xié)</b><b class='flag-5'>程</b>的那些事兒

    協(xié)和線程有什么區(qū)別

    協(xié)和線程的區(qū)別協(xié)和線程的共同目的之一是實(shí)現(xiàn)系統(tǒng)資源的上下文調(diào)用,不過它們的實(shí)現(xiàn)層級不同;線程(Thraed)是比進(jìn)程小一級的的運(yùn)行單位,多線程實(shí)現(xiàn)系統(tǒng)資源上下文調(diào)用,是編程語言交付
    發(fā)表于 12-10 06:23

    Python中的多核CPU共享數(shù)據(jù)之協(xié)詳解

    協(xié)又稱微線程,coroutne,協(xié)是一種用戶態(tài)的輕量級線程。通俗點(diǎn)講就是周末我在家里休息,假如我先洗漱,再煮飯,再下載電影看會很慢,用了協(xié)
    的頭像 發(fā)表于 12-07 10:23 ?6529次閱讀
    Python中的多核CPU共享數(shù)據(jù)之<b class='flag-5'>協(xié)</b><b class='flag-5'>程</b>詳解

    關(guān)于C++ 20協(xié)最全面詳解

    花了一兩周的時間后,我想寫寫 C++20 協(xié)的基本用法,因?yàn)?C++ 的協(xié)讓我感到很奇怪,寫一個協(xié)
    的頭像 發(fā)表于 04-12 11:10 ?1.3w次閱讀
    關(guān)于C++ 20<b class='flag-5'>協(xié)</b><b class='flag-5'>程</b>最全面詳解

    Python后端項(xiàng)目的協(xié)是什么

    最近公司 Python 后端項(xiàng)目進(jìn)行重構(gòu),整個后端邏輯基本都變更為采用“異步”協(xié)的方式實(shí)現(xiàn)??粗鴿M屏幕經(jīng)過 async await(協(xié)在 Python 中的實(shí)現(xiàn))修飾的代碼,我頓時
    的頭像 發(fā)表于 09-23 14:38 ?1284次閱讀

    Python協(xié)與JavaScript協(xié)的對比及經(jīng)驗(yàn)技巧

    前言以前沒怎么接觸前端,對 JavaScript 的異步操作不了解,現(xiàn)在有了點(diǎn)了解。一查發(fā)現(xiàn) Python 和 JavaScript 的協(xié)發(fā)展史簡直就是一毛一樣!這里大致做下橫向?qū)Ρ群涂偨Y(jié),便于
    的頭像 發(fā)表于 10-20 14:30 ?1821次閱讀

    通過例子由淺入深的理解yield協(xié)

    send:send() 方法致使協(xié)程前進(jìn)到下一個yield 語句,另外,生成器可以作為協(xié)使用
    的頭像 發(fā)表于 08-23 11:12 ?1952次閱讀

    詳解Linux線程、線程與異步編程、協(xié)與異步

    協(xié)不是系統(tǒng)級線程,很多時候協(xié)被稱為“輕量級線程”、“微線程”、“纖(fiber)”等。簡單來說可以認(rèn)為
    的頭像 發(fā)表于 03-16 15:49 ?915次閱讀

    協(xié)的概念及協(xié)的掛起函數(shù)介紹

    協(xié)是一種輕量級的線程,它可以在單個線程中實(shí)現(xiàn)并發(fā)執(zhí)行。與線程不同,協(xié)不需要操作系統(tǒng)的上下文切換,因此可以更高效地使用系統(tǒng)資源。Kotlin 協(xié)
    的頭像 發(fā)表于 04-19 10:20 ?836次閱讀

    Kotlin協(xié)實(shí)戰(zhàn)進(jìn)階之筑基篇3

    協(xié)的概念在1958年就開始出現(xiàn)(比線程還早), 目前很多語言開始原生支, Java 沒有原生協(xié)但是大型公司都自己或者使用第三方庫來支持協(xié)
    的頭像 發(fā)表于 05-30 16:26 ?627次閱讀

    FreeRTOS任務(wù)與協(xié)介紹

    FreeRTOS 中應(yīng)用既可以使用任務(wù),也可以使用協(xié)(Co-Routine),或者兩者混合使用。但是任務(wù)和協(xié)使用不同的API函數(shù),因此不能通過隊(duì)列(或信號量)將數(shù)據(jù)從任務(wù)發(fā)送給協(xié)
    的頭像 發(fā)表于 09-28 11:02 ?905次閱讀

    協(xié)的作用、結(jié)構(gòu)及原理

    本文介紹了協(xié)的作用、結(jié)構(gòu)、原理,并使用C++和匯編實(shí)現(xiàn)了64位系統(tǒng)下的協(xié)池。文章內(nèi)容避免了協(xié)
    的頭像 發(fā)表于 11-08 16:39 ?1008次閱讀
    <b class='flag-5'>協(xié)</b><b class='flag-5'>程</b>的作用、結(jié)構(gòu)及原理

    C/C++協(xié)編程的相關(guān)概念和技巧

    一、引言 協(xié)的定義和背景 協(xié)(Coroutine),又稱為微線程或者輕量級線程,是一種用戶態(tài)的、可在單個線程中并發(fā)執(zhí)行的程序組件。協(xié)
    的頭像 發(fā)表于 11-09 11:34 ?595次閱讀

    協(xié)的實(shí)現(xiàn)與原理

    前言 協(xié)這個概念很久了,好多程序員是實(shí)現(xiàn)過這個組件的,網(wǎng)上關(guān)于協(xié)的文章,博客,論壇都是汗牛充棟,在知乎,github上面也有很多大牛寫了關(guān)于協(xié)
    的頭像 發(fā)表于 11-10 10:57 ?382次閱讀

    Linux線程、線程與異步編程、協(xié)與異步介紹

    協(xié)不是系統(tǒng)級線程,很多時候協(xié)被稱為“輕量級線程”、“微線程”、“纖(fiber)”等。簡單來說可以認(rèn)為
    的頭像 發(fā)表于 11-11 11:35 ?940次閱讀
    Linux線程、線程與異步編程、<b class='flag-5'>協(xié)</b><b class='flag-5'>程</b>與異步介紹