go实例之线程池
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:只能发送数据
如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!!