登录
首页 >  Golang >  Go问答

改变脚本以实现多线程操作

来源:stackoverflow

时间:2024-03-02 18:18:24 287浏览 收藏

在IT行业这个发展更新速度很快的行业,只有不停止的学习,才不会被行业所淘汰。如果你是Golang学习者,那么本文《改变脚本以实现多线程操作》就很适合你!本篇内容主要包括##content_title##,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

我使用代码的方式是从文件传递一个 url 列表,并使用我的代码运行每个 url,该代码使用 bufio,因此我可以通过管道传输文件中的 url。

命令:cat test2.txt | ./mygofile

https://beap.adss.yahoo.com/
https://id.answers.yahoo.com/search
https://brokenurl
https://id.answers.yahoo.com/knowledgesearchservice
https://id.answers.yahoo.com/question/nextquestion

示例 url 的内容

package main

import (
    "log"
    "bufio"
    "bytes"
    "fmt"
    "net/http"
    "os"
    "strings"
    "crypto/tls"
)

func main() {
    tr := http.DefaultTransport.(*http.Transport).Clone()
    tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
    client := &http.Client{Transport: tr}

    passedUrl := bufio.NewScanner(os.Stdin)
    var pUrl string
    for passedUrl.Scan() {
        fmt.Println(passedUrl.Text())
        if strings.Contains(passedUrl.Text(), "://"){
            pUrl = passedUrl.Text()
        } else {
            pUrl = "https://" + passedUrl.Text()
        }

        body := ""

        req, err := http.NewRequest("POST", pUrl, bytes.NewBuffer([]byte(body)))
        if err != nil {
            log.Println(err)
        }

        req.Header.Add("Content-Type", "application/xml; charset=utf-8")
        resp, err := client.Do(req)
        if err != nil {
            log.Println(err)
            continue // stop here and process next item
        }

        defer resp.Body.Close()

    }
}

问题是,当我给出大量网址列表时,代码非常慢。有什么方法可以使代码多线程或以简单的方式更快


解决方案


创建工作协程池。 worker goroutine 从通道获取要处理的 url,并在通道关闭时退出。主 goroutine 将 url 提供给通道并在完成后关闭通道。

tr := http.DefaultTransport.(*http.Transport).Clone()
tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{Transport: tr}

var wg sync.WaitGroup
work := make(chan string)
for i := 0; i < 10; i++ {
    wg.Add()
    go func() {
        defer wg.Done()
        for pUrl := range work {
            fmt.Println(purl)
            if !strings.Contains(purl, "://") {
                pUrl = "https://" + passedUrl.Text()
            }

            body := ""

            req, err := http.NewRequest("POST", pUrl, strings.NewReader(body))
            if err != nil {
                log.Println(err)
                continue
            }

            req.Header.Add("Content-Type", "application/xml; charset=utf-8")
            resp, err := client.Do(req)
            if err != nil {
                log.Println(err)
                continue // stop here and process next item
            }

            // do something with resp

            resp.Body.Close()

        }
    }()
}

passedUrl := bufio.NewScanner(os.Stdin)
for passedUrl.Scan() {
    work <- passedUrl.Text()
}
close(work) // signal workers to exit
wg.Wait()   // wait for workers to exit

到这里,我们也就讲完了《改变脚本以实现多线程操作》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>