欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語(yǔ)言使用Goroutine并發(fā)打印的項(xiàng)目實(shí)踐

 更新時(shí)間:2025年08月14日 10:40:14   作者:程序員愛釣魚  
本文通過(guò)并發(fā)打印任務(wù)案例,講解Go語(yǔ)言Goroutine的使用、同步控制及高并發(fā)優(yōu)勢(shì),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

在本篇文章中,我們將從最基礎(chǔ)的 Goroutine 并發(fā)模型入手,逐步掌握 Go 語(yǔ)言中并發(fā)控制的核心思想。通過(guò)一個(gè)簡(jiǎn)單的“并發(fā)打印任務(wù)”案例,掌握 Goroutine 的使用、輸出順序的控制、主協(xié)程退出時(shí)機(jī)等關(guān)鍵知識(shí)。

一、為什么學(xué)習(xí) Goroutine?

Goroutine 是 Go 語(yǔ)言最核心的并發(fā)原語(yǔ)。相比于線程,它更加輕量:

  • 啟動(dòng)成本極低(大約只需 2KB 內(nèi)存)
  • 數(shù)量可以輕松達(dá)到上萬(wàn)甚至百萬(wàn)級(jí)
  • 使用非常簡(jiǎn)單,只需一個(gè) go 關(guān)鍵字

Go 的并發(fā)理念是:不要通過(guò)共享內(nèi)存來(lái)通信,而要通過(guò)通信來(lái)共享內(nèi)存。

掌握 Goroutine,是理解 Go 并發(fā)模型的第一步。

二、實(shí)戰(zhàn)目標(biāo)

我們將實(shí)現(xiàn)一個(gè)小項(xiàng)目:

  1. 啟動(dòng)多個(gè) Goroutine 并發(fā)打印任務(wù)信息
  2. 每個(gè)任務(wù)打印固定內(nèi)容
  3. 確保主程序等待所有任務(wù)完成
  4. 引入 sync.WaitGroup 實(shí)現(xiàn)同步控制

三、基礎(chǔ)版本:?jiǎn)?dòng)多個(gè) Goroutine

下面是最簡(jiǎn)單的 Goroutine 并發(fā)打印實(shí)現(xiàn):

package main

import (
    "fmt"
    "time"
)

func printTask(id int) {
    fmt.Printf("任務(wù) %d 正在執(zhí)行\(zhòng)n", id)
}

func main() {
    for i := 1; i <= 5; i++ {
        go printTask(i)
    }

    // 給協(xié)程一點(diǎn)時(shí)間完成(不推薦的方式)
    time.Sleep(time.Second)
    fmt.Println("主程序結(jié)束")
}

運(yùn)行結(jié)果(示例):

任務(wù) 2 正在執(zhí)行
任務(wù) 4 正在執(zhí)行
任務(wù) 1 正在執(zhí)行
任務(wù) 3 正在執(zhí)行
任務(wù) 5 正在執(zhí)行
主程序結(jié)束

你會(huì)注意到,輸出順序可能與代碼中的順序不同,這是并發(fā)執(zhí)行的結(jié)果。

四、問(wèn)題:主程序過(guò)早退出

在上面例子中我們使用了 time.Sleep 來(lái)“湊時(shí)間”,這是一種不可靠且危險(xiǎn)的方式。如果任務(wù)執(zhí)行時(shí)間更長(zhǎng),就會(huì)被主程序強(qiáng)制退出。

為了解決這個(gè)問(wèn)題,我們引入 sync.WaitGroup。

五、進(jìn)階版本:使用 WaitGroup 等待所有 Goroutine 完成

package main

import (
    "fmt"
    "sync"
    "time"
)

// 模擬執(zhí)行任務(wù)
func printTask(id int, wg *sync.WaitGroup) {
    defer wg.Done() // 標(biāo)記一個(gè)任務(wù)完成
    fmt.Printf("任務(wù) %d 開始執(zhí)行\(zhòng)n", id)
    time.Sleep(time.Duration(id) * 200 * time.Millisecond) // 模擬不同任務(wù)耗時(shí)
    fmt.Printf("任務(wù) %d 執(zhí)行完畢\n", id)
}

func main() {
    var wg sync.WaitGroup

    taskCount := 5
    for i := 1; i <= taskCount; i++ {
        wg.Add(1) // 增加一個(gè)任務(wù)
        go printTask(i, &wg)
    }

    wg.Wait() // 等待所有任務(wù)完成
    fmt.Println("所有任務(wù)完成,主程序退出")
}

輸出示例:

任務(wù) 1 開始執(zhí)行
任務(wù) 2 開始執(zhí)行
任務(wù) 3 開始執(zhí)行
任務(wù) 4 開始執(zhí)行
任務(wù) 5 開始執(zhí)行
任務(wù) 1 執(zhí)行完畢
任務(wù) 2 執(zhí)行完畢
任務(wù) 3 執(zhí)行完畢
任務(wù) 4 執(zhí)行完畢
任務(wù) 5 執(zhí)行完畢
所有任務(wù)完成,主程序退出

六、重點(diǎn)知識(shí)點(diǎn)解析

1.go關(guān)鍵字

只需在函數(shù)前加 go,即可將該函數(shù)交由調(diào)度器異步執(zhí)行,立即返回。

2.sync.WaitGroup

  • wg.Add(n):添加 n 個(gè)任務(wù)
  • wg.Done():在任務(wù)完成后調(diào)用
  • wg.Wait():阻塞主線程,直到所有任務(wù)完成

3.defer用法

使用 defer wg.Done() 可以確保即使函數(shù)中途返回也能正確減計(jì)數(shù)。

七、延伸思考

  • 若有 10萬(wàn)個(gè)任務(wù)要并發(fā)執(zhí)行,Goroutine 是否能承載?(答案是:可以,但建議使用并發(fā)控制池)
  • 如果某個(gè)任務(wù)失敗,是否能提前取消其他任務(wù)?(答案是:可以結(jié)合 context 實(shí)現(xiàn))

八、真實(shí)應(yīng)用場(chǎng)景舉例

  • 批量調(diào)用多個(gè)接口(如:并發(fā)請(qǐng)求天氣接口、發(fā)郵件)
  • 批量處理文件(壓縮、上傳、轉(zhuǎn)碼)
  • 并發(fā)爬蟲(抓取多個(gè)頁(yè)面)
  • 消息隊(duì)列并發(fā)消費(fèi)任務(wù)

九、小結(jié)

本文通過(guò)“并發(fā)打印任務(wù)”這一簡(jiǎn)單示例,向你展示了 Go 并發(fā)編程的基本能力:

  • 啟動(dòng) Goroutine 的方法
  • 并發(fā)任務(wù)間的非確定性
  • 如何使用 WaitGroup 來(lái)保證主程序的正確退出
  • Goroutine 的輕量特性,適合高并發(fā)場(chǎng)景

并發(fā)是 Go 的靈魂,控制好協(xié)程的生命周期和調(diào)度能力,將直接影響系統(tǒng)的健壯性與性能。

到此這篇關(guān)于Go語(yǔ)言使用Goroutine并發(fā)打印的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)Go Goroutine并發(fā)打印內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • go基于Gin框架的HTTP接口限速實(shí)踐

    go基于Gin框架的HTTP接口限速實(shí)踐

    HTTP接口在各個(gè)業(yè)務(wù)模塊之間扮演著重要的角色,本文主要介紹了go基于Gin框架的HTTP接口限速實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • go語(yǔ)言制作一個(gè)gif動(dòng)態(tài)圖

    go語(yǔ)言制作一個(gè)gif動(dòng)態(tài)圖

    這篇文章主要介紹了go制作一個(gè)gif動(dòng)態(tài)圖的相關(guān)資料,需要的朋友可以參考下
    2015-03-03
  • Go?并發(fā)編程協(xié)程及調(diào)度機(jī)制詳情

    Go?并發(fā)編程協(xié)程及調(diào)度機(jī)制詳情

    這篇文章主要介紹了Go并發(fā)編程協(xié)程及調(diào)度機(jī)制詳情,協(xié)程是Go語(yǔ)言最大的特色之一,goroutine的實(shí)現(xiàn)其實(shí)是通過(guò)協(xié)程,更多相關(guān)內(nèi)容需要的朋友可以參考一下
    2022-09-09
  • Golang中panic的異常處理

    Golang中panic的異常處理

    本文主要介紹了Golang中panic的異常處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Go語(yǔ)言實(shí)現(xiàn)JSON解析的方法詳解

    Go語(yǔ)言實(shí)現(xiàn)JSON解析的方法詳解

    在日常項(xiàng)目中,使用Json格式進(jìn)行數(shù)據(jù)封裝是比較常見的操作。本文將詳細(xì)講解如何利用Go語(yǔ)言實(shí)現(xiàn)JSON的解析,感興趣的小伙伴可以學(xué)習(xí)一下
    2022-04-04
  • 淺談Golang是如何讀取文件內(nèi)容的(7種)

    淺談Golang是如何讀取文件內(nèi)容的(7種)

    這篇文章主要介紹了淺談Golang是如何讀取文件內(nèi)容的,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • GoLang string類型深入分析

    GoLang string類型深入分析

    string 作為 go 語(yǔ)言中的基礎(chǔ)類型,其實(shí)有一些需要反復(fù)揣摩的,可能是我們使用的場(chǎng)景太簡(jiǎn)單,也可能是我們不需要那可憐的一點(diǎn)優(yōu)化來(lái)提高性能,對(duì)它也就沒那么上心了
    2023-01-01
  • go內(nèi)置函數(shù)copy()的具體使用

    go內(nèi)置函數(shù)copy()的具體使用

    當(dāng)我們?cè)贕o語(yǔ)言中需要將一個(gè)切片的內(nèi)容復(fù)制到另一個(gè)切片時(shí),可以使用內(nèi)置的copy()函數(shù),本文就介紹了go內(nèi)置函數(shù)copy()的具體使用,感興趣的可以了解一下
    2023-08-08
  • 阿里云go開發(fā)環(huán)境搭建過(guò)程

    阿里云go開發(fā)環(huán)境搭建過(guò)程

    這篇文章主要介紹了阿里云go開發(fā)環(huán)境搭建過(guò)程,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • go run main.go 一直提示找不到包的解決方案

    go run main.go 一直提示找不到包的解決方案

    這篇文章主要介紹了go run main.go 一直提示找不到包的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04

最新評(píng)論