在Go中應(yīng)用goroutine池瞒爬,一般是為了限制同時(shí)運(yùn)行的goroutine數(shù)量,以避免資源過(guò)度消耗腌闯。goroutine池可以通過(guò)創(chuàng)建一個(gè)工作隊(duì)列和一個(gè)固定數(shù)量的工作者來(lái)實(shí)現(xiàn)。以下是一個(gè)goroutine池的實(shí)現(xiàn)示例:
package main
import (
"fmt"
"time"
)
// Job 表示需要處理的任務(wù)
type Job struct {
id int
workload int
}
// Worker 表示工作者
func Worker(id int, jobs <-chan Job, results chan<- int) {
for job := range jobs {
fmt.Printf("Worker %d processing job %d\n", id, job.id)
time.Sleep(time.Duration(job.workload) * time.Second) // 模擬工作時(shí)間
results <- job.id
}
}
func main() {
const numJobs = 5 // 總?cè)蝿?wù)數(shù)
const numWorkers = 3 // 工作者數(shù)
jobs := make(chan Job, numJobs) // 創(chuàng)建任務(wù)隊(duì)列
results := make(chan int, numJobs) // 創(chuàng)建結(jié)果隊(duì)列
// 啟動(dòng)工作者
for w := range numWorkers {
go Worker(w, jobs, results)
}
// 發(fā)送任務(wù)到任務(wù)隊(duì)列
for j := 0; j < numJobs; j++ {
jobs <- Job{id: j, workload: j + 1}
}
close(jobs) // 關(guān)閉任務(wù)隊(duì)列
// 收集結(jié)果
for a := 0; a < numJobs; a++ {
result := <-results
fmt.Printf("Job %d done\n", result)
}
}
代碼解析:
- Job結(jié)構(gòu)體:表示一個(gè)任務(wù),其中包含任務(wù)ID和工作負(fù)載(模擬任務(wù)所需的時(shí)間)阳距。
- Worker函數(shù):表示工作者,從
jobs
通道中獲取任務(wù)并處理结借,然后將結(jié)果發(fā)送到results
通道筐摘。 - jobs通道:用于分發(fā)任務(wù)給工作者。
- results通道:用于接收工作者完成任務(wù)后的結(jié)果船老。
執(zhí)行過(guò)程:
- 主函數(shù)中先創(chuàng)建了
jobs
和results
兩個(gè)通道咖熟。 - 然后啟動(dòng)了一定數(shù)量的goroutine,每個(gè)goroutine都調(diào)用
Worker
函數(shù)并開(kāi)始等待任務(wù)柳畔。 - 主程序?qū)⑷蝿?wù)發(fā)送到
jobs
通道馍管,然后關(guān)閉通道以表示沒(méi)有更多任務(wù)。 - 最后薪韩,主程序等待從
results
通道接收所有任務(wù)的結(jié)果并輸出确沸。
通過(guò)這種方式,可以有效地控制同時(shí)運(yùn)行的goroutine數(shù)量俘陷,避免系統(tǒng)資源過(guò)度消耗罗捎。