Golang Go语言中协程请求数据

发布于 1周前 作者 yibo5220 来自 Go语言

我一个接口里边,需要多次操作数据库,现在想通过协程来实现。 下边这个 demo 是一个样例, 我在 resp 怎么区分协程的返回值,这里边还有些不太清晰。

func main() {
    var ch = make(chan []byte)
    go request("https://www.baidu.com", ch)
    go request("https://www.taobao.com", ch)
    go request("https://www.google.com", ch)
i := 0
timer := time.NewTimer(time.Second * 3)

L: for { select { case <-timer.C: break L case resp := <-ch: fmt.Printf("%d\n", len(resp)) // 接收 3 个之后关闭 chan i++ if i == 3 { close(ch) break L } } } // more code… }


Golang Go语言中协程请求数据

更多关于Golang Go语言中协程请求数据的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

你是要区分每个协程的返回值吗?不同的协程对应不同处理方式?

那么再构建一个一个结构体,例如:

type CRes struct {

}

更多关于Golang Go语言中协程请求数据的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你是要区分每个协程的返回值吗?不同的协程(或者说:不同的数据库)对应不同处理方式?

那么再构建一个一个结构体,例如:


type CRes struct {
ChannelType int // taobao:1, baidu:2, google:3
Res interfact{}
}



ch := make(chan CRes)

每个协程函数返回 CRes ,然后将 CRes 返回到 channel 中。在接受、处理 channel 的函数中,根据不同的 channelType 进行处理

明白了,谢谢你。

我修改后的 demo 发下

package main

import (
“fmt”
“time”
)

type CRes struct {
ChannelType int
Res interface{}
}

func main() {
var ch = make(chan CRes)
go test1(ch)
go test2(ch)
for i := 0; i < 2; i++ {
select {
case <-time.After(time.Second * 5):
fmt.Println(“超时操作”)
break
case resp := <-ch:
if resp.ChannelType == 1 {
fmt.Printf(“这是 1 的数据”)
}
if resp.ChannelType == 2 {
fmt.Printf(“这是 2 的数据”)
}
break
default:
fmt.Println(“资源已满,请稍后再试”)
}
}
}
func test1(ch chan CRes) {
res := CRes{
ChannelType: 1,
Res: nil,
}
ch <- res
}

func test2(ch chan CRes) {
res := CRes{
ChannelType: 2,
Res: nil,
}
ch <- res
}

md5(url) 作为任务的 ID ,返回的时候也对应的带上这个 ID 。

context 带个 id 进去

没必要这么复杂吧,直接用 errgroup 。最近有个协程的库看起来还可以 https://github.com/sourcegraph/conc

在Go语言中,协程(goroutine)是一种轻量级的线程,由Go运行时管理,用于并发执行任务。使用协程请求数据是一种常见的并发编程模式,可以显著提高程序的性能和响应速度。

当你需要在Go中使用协程请求数据时,通常会用到net/http包来发起HTTP请求。以下是一个简单的示例,展示了如何使用协程来并发地请求多个URL的数据:

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "sync"
)

func fetchData(url string, wg *sync.WaitGroup, results chan<- string) {
    defer wg.Done()
    resp, err := http.Get(url)
    if err != nil {
        results <- fmt.Sprintf("Error fetching %s: %v", url, err)
        return
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        results <- fmt.Sprintf("Error reading response from %s: %v", url, err)
        return
    }
    results <- fmt.Sprintf("Data from %s: %s", url, body)
}

func main() {
    var wg sync.WaitGroup
    results := make(chan string, 10)
    urls := []string{"http://example.com", "http://another-example.com"}
    for _, url := range urls {
        wg.Add(1)
        go fetchData(url, &wg, results)
    }
    wg.Wait()
    close(results)
    for result := range results {
        fmt.Println(result)
    }
}

这个示例中,我们使用了sync.WaitGroup来等待所有协程完成,并使用一个通道results来收集每个协程的结果。这样,你就可以并发地请求多个URL的数据,并在所有请求完成后处理结果。

回到顶部