如何让多个对象从一个go子程序中获取数据

How to allow multiple objects get data from a single go subroutine

我有一个案例,我想启动一个 go 子例程,它会定期从源中获取一些数据。如果调用失败,它将存储错误直到下一次调用成功。现在代码中有几个实例,其中一个实例将访问由 go 子例程提取的数据。我怎样才能实现这样的东西?

更新

我睡了一觉,喝了咖啡,我想我需要使用 java-ish 语义更连贯地重新表述问题。

我想出了一个基本的单例模式,returns 我是一个接口实现,它是 运行 一个永远循环内部的 go 子例程(让我们把永远循环的主要错误放在一边片刻)。问题是这个接口实现正被多个线程访问,以获取 go 子例程收集的数据。本质上,子程序每 10 分钟提取一次数据,然后无限次地请求数据。我怎样才能实现这样的东西?

您可以为此使用通道,但那样您将推送数据而不是拉取数据。我想那不会是个问题。

var channelXY = make(chan struct{}, 5000) //Change queue limits to your need, if push is much faster than pull you need to calculate the buffer

go func(channelXY <- chan struct{}) 
    for struct{} := range channelXY {
        //DO STUFF
    }
    WaitGroup.Done()
}(channelXY)

go func() {
    channelXY <- struct{}
}

记得用 WaitGroup 管理所有例程,否则您的程序将在所有例程完成之前结束。

编辑:关闭频道以停止 channel-read go-routine:

close(channelXY)

这是一个非常基本的示例,说明如何定期获取和收集数据。

请记住:运行这段代码不会像 main return 那样在任何事情真正发生之前不做任何事情,但是你如何处理它取决于你的具体用例。这段代码真的很简单,需要改进。这是部分问题的可能解决方案的草图:)

我在这里没有处理错误,但你可以像处理获取的数据一样处理它们(因此,多一个错误通道和一个从中读取的 goroutine)。

func main() {

    period := time.Second
    respChan := make(chan string)
    cancelChan := make(chan struct{})
    dataCollection := []string

    // periodicaly fetch data and send it to respChan
    go func(period time.Duration, respChan chan string, cancelChan chan struct{}) {
        ticker := time.Ticker(period)
        for {
            select {
            case <-ticker.C:
                go fetchData(respChan)
            case <-cancelChan:
                // close respChan to stop reading goroutine
                close(respChan)
                return
            }
        }
    }(period, cancelChan)

    // read from respChan and write to dataCollection
    go func(respChan chan string) {
        for data := range respChan {
            dataCollection = append(dataCollection, data)
        }
    }(respChan)

    // close cancelChan to gracefuly stop the app
    // close(cancelChan)
}


func fetchData(respChan chan string) {
    data := "fetched data"
    respChan <- data
}