1

我想在 Go 中创建一个带有 manager 程序的生产者/消费者。例如:我有一个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 有特定的方法来做到这一点?

4

2 回答 2

2

我做了一个与你尝试做的非常相似的例子,检查这个 gist github gist

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

于 2013-12-23T14:31:54.420 回答
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)
}
于 2013-12-23T16:40:03.720 回答