**如代码所示,十个下载任务,三个工作池,工作池中线程执行为串行,总运行时间大于任一线程的下载时间,比较可得工作效率比十个goroutine并行低很多,是不是说明工作池的作用只有限制线程数,是不是只有在高并发环境下才适用**
```go
package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
t1 := time.Now()
Queue := make(chan error, 10)
result := make(chan string, 10)
//十个任务
urls := []string{
"http://dlsw.baidu.com/sw-search-sp/soft/44/17448/Baidusd_Setup_4.2.0.7666.1436769697.exe",
"http://dlsw.baidu.com/sw-search-sp/soft/3a/12350/QQ_V7.4.15197.0_setup.1436951158.exe",
"http://dlsw.baidu.com/sw-search-sp/soft/9d/14744/ChromeStandalone_V43.0.2357.134_Setup.1436927123.exe",
"http://dlsw.baidu.com/sw-search-sp/soft/6f/15752/iTunes_V12.2.1.16_Setup.1436855012.exe",
"http://dlsw.baidu.com/sw-search-sp/soft/70/17456/BaiduAn_Setup_5.0.0.6747.1435912002.exe",
"http://dlsw.baidu.com/sw-search-sp/soft/40/12856/QIYImedia_1_06_v4.0.0.32.1437470004.exe",
"http://dlsw.baidu.com/sw-search-sp/soft/42/37473/BaiduSoftMgr_Setup_7.0.0.1274.1436770136.exe",
"http://dlsw.baidu.com/sw-search-sp/soft/49/16988/YoudaoNote_V4.1.0.300_setup.1429669613.exe",
"http://dlsw.baidu.com/sw-search-sp/soft/55/11339/bdbrowserSetup-7.6.100.2089-1212_11000003.1437029629.exe",
"http://dlsw.baidu.com/sw-search-sp/soft/53/21734/91zhushoupc_Windows_V5.7.0.1633.1436844901.exe",
}
for id := range urls {
//遍历下载
result <- urls[id]
}
for i := 1; i <= 3; i++ {
go WorkPool(1, result, Queue)
}
for i := 1; i <= 10; i++ {
fmt.Println(<-Queue)
}
elapsed := time.Since(t1)
fmt.Println("总运行时间", elapsed)
}
//下载操作
func Download(id int, url string) error {
t1 := time.Now()
fmt.Println("开始下载。。。", url)
sp := strings.Split(url, "/")
filename := sp[len(sp)-1]
//创建文件夹
file, err := os.Create("static/" + filename)
if err != nil {
return err
}
res, err := http.Get(url)
if err != nil {
return err
}
lenth, err := io.Copy(file, res.Body)
if err != nil {
return err
}
elapsed := time.Since(t1)
fmt.Println(id, "线程池中下载完成", filename, "文件大小为", lenth, "下载时间时间", elapsed)
return nil
}
//工作池方法
func WorkPool(id int, result chan string, Queue chan error) {
for url := range result {
err := Download(id, url)
Queue <- err
}
}
```
工作池的作用并不是很明显,可以理解为限制 `Goroutine` 数,好处是传递任务方便,但是我觉得写不写都一样,没啥好处,你程序里的 id 有点不必要我感觉,这个是一个工作池的写法
```go
// In this example we'll look at how to implement
// a _worker pool_ using goroutines and channels.
package main
import "fmt"
import "time"
// Here's the worker, of which we'll run several
// concurrent instances. These workers will receive
// work on the `jobs` channel and send the corresponding
// results on `results`. We'll sleep a second per job to
// simulate an expensive task.
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("worker", id, "started job", j)
time.Sleep(time.Second)
fmt.Println("worker", id, "finished job", j)
results <- j * 2
}
}
func main() {
// In order to use our pool of workers we need to send
// them work and collect their results. We make 2
// channels for this.
jobs := make(chan int, 100)
results := make(chan int, 100)
// This starts up 3 workers, initially blocked
// because there are no jobs yet.
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// Here we send 5 `jobs` and then `close` that
// channel to indicate that's all the work we have.
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
// Finally we collect all the results of the work.
for a := 1; a <= 5; a++ {
<-results
}
}
```
#5
更多评论