关于Go中Channel和Goroutine实现工作池的问题

yinshidaoshi · 2017-12-14 12:04:08 · 1373 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-12-14 12:04:08 的主题,其中的信息可能已经有所发展或是发生改变。

如代码所示,十个下载任务,三个工作池,工作池中线程执行为串行,总运行时间大于任一线程的下载时间,比较可得工作效率比十个goroutine并行低很多,是不是说明工作池的作用只有限制线程数,是不是只有在高并发环境下才适用

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
    }
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1373 次点击  
加入收藏 微博
10 回复  |  直到 2017-12-20 07:16:41
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传