go語言使用goroutines
和channel
實現一個工作池相當簡單。使用goroutines
開指定書目線程,通道分別傳遞任務和任務結果。簡單的線程池代碼如下:
1 package main 2 3 import "fmt" 4 import "time" 5 6 // Here's the worker, of which we'll run several 7 // concurrent instances. These workers will receive 8 // work on the `jobs` channel and send the corresponding 9 // results on `results`. We'll sleep a second per job to 10 // simulate an expensive task. 11 func worker(id int, jobs <-chan int, results chan<- int) { 12 for j := range jobs { 13 fmt.Println("worker", id, "started job", j) 14 time.Sleep(time.Second) 15 fmt.Println("worker", id, "finished job", j) 16 results <- j * 2 17 } 18 } 19 20 func main() { 21 22 // In order to use our pool of workers we need to send 23 // them work and collect their results. We make 2 24 // channels for this. 25 jobs := make(chan int, 100) 26 results := make(chan int, 100) 27 28 // This starts up 3 workers, initially blocked 29 // because there are no jobs yet. 30 for w := 1; w <= 3; w++ { 31 go worker(w, jobs, results) 32 } 33 34 // Here we send 5 `jobs` and then `close` that 35 // channel to indicate that's all the work we have. 36 for j := 1; j <= 5; j++ { 37 jobs <- j 38 } 39 close(jobs) 40 41 // Finally we collect all the results of the work. 42 for a := 1; a <= 5; a++ { 43 <-results 44 } 45 }
執行上面代碼,將得到以下輸出結果
1 worker 3 started job 2 2 worker 1 started job 1 3 worker 2 started job 3 4 worker 3 finished job 2 5 worker 3 started job 4 6 worker 1 finished job 1 7 worker 1 started job 5 8 worker 2 finished job 3 9 worker 3 finished job 4 10 worker 1 finished job 5
看代碼中注釋也大概能理解每一步的含義,代碼25行和26行分別初始化了2個通道,用於發送任務給子線程和接收子線程計算的任務結果。30-32行代碼是啟動了3個子線程,用於處理任務,並將任務通道和結果通道傳遞給了線程函數。36-38行代碼是發送任務到jobs通道,工作線程在沒有任務時,是阻塞着等待任務,當發現任務通道中有任務時,開始執行任務,當任務執行完畢時,將任務結果發送給結果通道。
jobs <-chan int:只能接收數據
results chan<- int:只能發送數據
如果您覺得文章不錯,不妨給個打賞,寫作不易,感謝各位的支持。您的支持是我最大的動力,謝謝!!!