CodeFun Go

代码Go实现工作池

假设有一组任务需要异步处理且量很大,那我们需要同时开启多个 worker 以保证任务的处理速度而不会堵塞任务。

我们可以使用使用协程与通道实现一个工作池。

创建2个信道,worker 用于传送任务消息,results 用于接收消息处理结果。

创建3个 Worker 协程,用于接收和处理来自 worker 信道的任务消息,并将处理结果通过信道 results 返回

package main

import (
	"fmt"
	"time"
	"errors"
)
type email struct {
	id int
	err error
}

func worker(id int, emailJobs <-chan email, results chan<- email) {
	for emailJob := range emailJobs {
		time.Sleep(time.Second)
		fmt.Printf("worker %d send email %d \n", id, emailJob.id)
		emailJob.err = errors.New("failure")
		results <- emailJob
	}
}

func main() {
	total := 5
	emailJobs := make(chan email, total)
	results := make(chan email, total)
	
	go worker(1, emailJobs, results)
	go worker(2, emailJobs, results)
	go worker(3, emailJobs, results)

	emailJobs <- email{1, nil}
	emailJobs <- email{2, nil}
	emailJobs <- email{3, nil}
	emailJobs <- email{4, nil}
	emailJobs <- email{5, nil}
    close(emailJobs)

	for j := 1; j <= total; j ++ {
        email := <-results
		fmt.Println("email ", email.id, email.err)
    }
	close(results)
}
worker 2 send email 3 
email  3 failure
worker 3 send email 1 
email  1 failure
worker 1 send email 2 
email  2 failure
worker 2 send email 4 
email  4 failure
worker 3 send email 5 
email  5 failure