Go 語言并不像其他一些語言(例如 Java 或 C#)那樣直接提供一個線程池的概念。相反,Go 使用 goroutines 來實現并發,它是一種比線程更輕量級的并發執行單元。不過,仍然可以實現一個類似線程池的結構,來管理和限制同時運行的 goroutines 的數量。以下是如何在 Go 中實現一個簡單的類似線程池的功能的例子:
package mainimport ("fmt""sync""time"
)// WorkerPool 結構體定義
type WorkerPool struct {jobs chan func() // 用于接收任務的通道maxJobs int // 最大并發任務數wg sync.WaitGroup // 用于等待所有任務完成
}// NewWorkerPool 創建一個新的 WorkerPool
func NewWorkerPool(maxJobs int) *WorkerPool {pool := &WorkerPool{jobs: make(chan func(), maxJobs),maxJobs: maxJobs,}return pool
}// Start 開始 WorkerPool 的工作
func (p *WorkerPool) Start() {for i := 0; i < p.maxJobs; i++ {go func() {for job := range p.jobs {job()}}()}
}// Submit 提交一個任務到 WorkerPool
func (p *WorkerPool) Submit(job func()) {p.wg.Add(1)p.jobs <- func() {defer p.wg.Done()job()}
}// Wait 等待所有任務完成
func (p *WorkerPool) Wait() {p.wg.Wait()close(p.jobs) // 關閉通道,停止接收新的任務
}func main() {// 創建一個最大并發數為 3 的工作池pool := NewWorkerPool(3)pool.Start()for i := 0; i < 10; i++ {i := i // 創建任務變量的本地副本pool.Submit(func() {fmt.Printf("Starting job %d\n", i)time.Sleep(2 * time.Second) // 模擬耗時操作fmt.Printf("Finished job %d\n", i)})}// 等待所有任務完成pool.Wait()fmt.Println("All jobs completed.")
}
在這個例子中,WorkerPool
結構體有一個 jobs
通道用于接收任務,一個 maxJobs
表示最大并發任務數,和一個 sync.WaitGroup
用于等待所有任務完成。Start
方法啟動了 maxJobs
數量的 goroutines,每個 goroutine 不斷地從 jobs
通道中接收并執行任務。Submit
方法用于提交新的任務到 jobs
通道,同時增加 WaitGroup
的計數。Wait
方法等待所有任務完成后關閉 jobs
通道。
在 main
函數中,創建了一個最大并發數為 3 的 WorkerPool
,提交了 10 個任務,然后調用 Wait
方法等待所有任務完成。
這個簡單的 WorkerPool
實現可以控制同時運行的 goroutines 數量,從而類似于其他語言中的線程池概念。當然,根據實際需求,你可以擴展和定制這個 WorkerPool
的實現,例如添加任務的優先級、錯誤處理、任務結果的收集等功能。