Go語言使用Goroutine并發(fā)打印的項目實踐
在本篇文章中,我們將從最基礎(chǔ)的 Goroutine 并發(fā)模型入手,逐步掌握 Go 語言中并發(fā)控制的核心思想。通過一個簡單的“并發(fā)打印任務(wù)”案例,掌握 Goroutine 的使用、輸出順序的控制、主協(xié)程退出時機等關(guān)鍵知識。
一、為什么學(xué)習(xí) Goroutine?
Goroutine 是 Go 語言最核心的并發(fā)原語。相比于線程,它更加輕量:
- 啟動成本極低(大約只需 2KB 內(nèi)存)
- 數(shù)量可以輕松達到上萬甚至百萬級
- 使用非常簡單,只需一個
go關(guān)鍵字
Go 的并發(fā)理念是:不要通過共享內(nèi)存來通信,而要通過通信來共享內(nèi)存。
掌握 Goroutine,是理解 Go 并發(fā)模型的第一步。
二、實戰(zhàn)目標
我們將實現(xiàn)一個小項目:
- 啟動多個 Goroutine 并發(fā)打印任務(wù)信息
- 每個任務(wù)打印固定內(nèi)容
- 確保主程序等待所有任務(wù)完成
- 引入
sync.WaitGroup實現(xiàn)同步控制
三、基礎(chǔ)版本:啟動多個 Goroutine
下面是最簡單的 Goroutine 并發(fā)打印實現(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é)程一點時間完成(不推薦的方式)
time.Sleep(time.Second)
fmt.Println("主程序結(jié)束")
}
運行結(jié)果(示例):
任務(wù) 2 正在執(zhí)行
任務(wù) 4 正在執(zhí)行
任務(wù) 1 正在執(zhí)行
任務(wù) 3 正在執(zhí)行
任務(wù) 5 正在執(zhí)行
主程序結(jié)束
你會注意到,輸出順序可能與代碼中的順序不同,這是并發(fā)執(zhí)行的結(jié)果。
四、問題:主程序過早退出
在上面例子中我們使用了 time.Sleep 來“湊時間”,這是一種不可靠且危險的方式。如果任務(wù)執(zhí)行時間更長,就會被主程序強制退出。
為了解決這個問題,我們引入 sync.WaitGroup。
五、進階版本:使用 WaitGroup 等待所有 Goroutine 完成
package main
import (
"fmt"
"sync"
"time"
)
// 模擬執(zhí)行任務(wù)
func printTask(id int, wg *sync.WaitGroup) {
defer wg.Done() // 標記一個任務(wù)完成
fmt.Printf("任務(wù) %d 開始執(zhí)行\(zhòng)n", id)
time.Sleep(time.Duration(id) * 200 * time.Millisecond) // 模擬不同任務(wù)耗時
fmt.Printf("任務(wù) %d 執(zhí)行完畢\n", id)
}
func main() {
var wg sync.WaitGroup
taskCount := 5
for i := 1; i <= taskCount; i++ {
wg.Add(1) // 增加一個任務(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ù)完成,主程序退出
六、重點知識點解析
1.go關(guān)鍵字
只需在函數(shù)前加 go,即可將該函數(shù)交由調(diào)度器異步執(zhí)行,立即返回。
2.sync.WaitGroup
wg.Add(n):添加 n 個任務(wù)wg.Done():在任務(wù)完成后調(diào)用wg.Wait():阻塞主線程,直到所有任務(wù)完成
3.defer用法
使用 defer wg.Done() 可以確保即使函數(shù)中途返回也能正確減計數(shù)。
七、延伸思考
- 若有 10萬個任務(wù)要并發(fā)執(zhí)行,Goroutine 是否能承載?(答案是:可以,但建議使用并發(fā)控制池)
- 如果某個任務(wù)失敗,是否能提前取消其他任務(wù)?(答案是:可以結(jié)合
context實現(xiàn))
八、真實應(yīng)用場景舉例
- 批量調(diào)用多個接口(如:并發(fā)請求天氣接口、發(fā)郵件)
- 批量處理文件(壓縮、上傳、轉(zhuǎn)碼)
- 并發(fā)爬蟲(抓取多個頁面)
- 消息隊列并發(fā)消費任務(wù)
九、小結(jié)
本文通過“并發(fā)打印任務(wù)”這一簡單示例,向你展示了 Go 并發(fā)編程的基本能力:
- 啟動 Goroutine 的方法
- 并發(fā)任務(wù)間的非確定性
- 如何使用 WaitGroup 來保證主程序的正確退出
- Goroutine 的輕量特性,適合高并發(fā)場景
并發(fā)是 Go 的靈魂,控制好協(xié)程的生命周期和調(diào)度能力,將直接影響系統(tǒng)的健壯性與性能。
到此這篇關(guān)于Go語言使用Goroutine并發(fā)打印的項目實踐的文章就介紹到這了,更多相關(guān)Go Goroutine并發(fā)打印內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- golang gin 框架 異步同步 goroutine 并發(fā)操作
- Go語言中的并發(fā)goroutine底層原理
- Go并發(fā)編程之goroutine使用正確方法
- Go 并發(fā)編程Goroutine的實現(xiàn)示例
- Golang 語言控制并發(fā) Goroutine的方法
- golang并發(fā)編程中Goroutine 協(xié)程的實現(xiàn)
- Go中Goroutines輕量級并發(fā)的特性及效率探究
- 使用Go?goroutine實現(xiàn)并發(fā)的Clock服務(wù)
- Go語言使用goroutine及通道實現(xiàn)并發(fā)詳解
- Go 控制協(xié)程(goroutine)的并發(fā)數(shù)量
相關(guān)文章
Go?并發(fā)編程協(xié)程及調(diào)度機制詳情
這篇文章主要介紹了Go并發(fā)編程協(xié)程及調(diào)度機制詳情,協(xié)程是Go語言最大的特色之一,goroutine的實現(xiàn)其實是通過協(xié)程,更多相關(guān)內(nèi)容需要的朋友可以參考一下2022-09-09

