【问题标题】:Concurrent Producer and Consumer in GoGo 中的并发生产者和消费者
【发布时间】:2014-01-11 17:39:25
【问题描述】:

我想在 Go 中创建一个带有管理器程序的生产者/消费者。例如:我有一个5 producers, 5 consumers and manager。生产者有their own local arrays,他们遍历它们并将元素发送给经理。消费者有their own local arrays 与元素消费的信息;他们也将它们发送给经理。管理器有它own array,它存储有什么和有多少元素(例如 - 如果生产者发送1 1 2 3 1 2 0 元素,管理器数组看起来像1 3 2 1(一个 0、三个 1、两个 2 和一个3 ) 它处理生产者和消费者的请求——将一个元素放入数组(生产)或删除它(消费)。

是否可以在 Go 中制作这样的程序?我已经在 J​​AVA + CSP 中使用通道来发送信息,并在管理器中使用守卫来确定当生产者和消费者尝试处理相同元素时应该首先执行哪个过程(例如,生产者想要将 1 添加到管理器数组同时消费者想要消费 1)。

欢迎提供任何示例或建议,因为我找不到任何关于我想做的事情的信息。如果需要,我可以提供我的 JAVA+CSP 代码。

更新。同步怎么样(不要从空数组中获取)?例如 - 如果消费者想要使用尚不存在的管理器数组中的元素(例如,消费者想要使用“3”,但管理器没有它们中的任何一个)但生产者有这个元素,它将在几个迭代 - 如何让消费者一次又一次地检查管理器数组,直到生产者工作完成?我是否需要为消费者元素创建结构(或类)并标记它们是否被使用,或者 Go 有特定的方法来做到这一点?

【问题讨论】:

    标签: concurrency go producer


    【解决方案1】:

    我做了一个与您尝试做的非常相似的示例,请查看此要点github gist

    我实现的方式是为我的流程消费者使用一个通道,另一个用于生产项目的 2x 流程,for 块控制从生产者到消费者的推送,并且每当生产者没有推送任何内容时,循环将default。通过通道移动的对象是切片,进程将在通过通道发送的每个切片中生成和消费标题。我相信您可以调整此代码以适合您的示例。

    【讨论】:

    • 谢谢你的回答和例子,我会试试的!
    • 祝您好运,如果您需要进一步的帮助,请随时在此处发表评论。
    【解决方案2】:

    这是一个完整的示例,包括频道清理。在所有的消费者和生产者都完成后,Manager 打印出结果(我使用的是地图而不是切片,因为我认为它使代码更容易一点)。

    package main
    
    import "fmt"
    
    // Consume processes the numbers in ns, sending them on ch after they're
    // processed. When the routine is finished, it signals that on done.
    func Consume(done chan bool, ch chan int, ns []int) {
        for i := range ns {
            ch <- i
        }
        done <- true
    }
    
    // Produce "creates" the numbers in ns, sending them on ch after they're
    // produced. When the routine is finished, it signals that on done.
    func Produce(done chan bool, ch chan int, ns []int) {
        for i := range ns {
            ch <- i
        }
        done <- true
    }
    
    // Manage creates consumers and producers for the given int slices.
    // It returns once all consumers and producers are finished.
    func Manage(cons, pros [][]int) {
        cch := make(chan int)
        pch := make(chan int)
        dch := make(chan bool)
        n := len(cons) + len(pros)
        data := make(map[int]int)
        for _, c := range cons {
            go Consume(dch, cch, c)
        }
        for _, p := range pros {
            go Produce(dch, pch, p)
        }
        for n > 0 {
            select {
            case c := <-cch:
                data[c] -= 1
            case c := <-pch:
                data[c] += 1
            case <-dch:
                n -= 1
            }
        }
        close(cch)
        close(pch)
        close(dch)
        fmt.Println(data)
    }
    func main() {
        cons := [][]int{{1, 3, 5}, {0, 1, 5}}
        pros := [][]int{{0, 1, 1}, {3, 5, 5, 7}}
        Manage(cons, pros)
    }
    

    【讨论】:

    • 只需将这一行 for i := range ns 更改为 for _, i := range ns ,一切都按预期工作,谢谢。但是现在我有其他问题,我更新了我的问题,如果你可以看看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多