2013-12-23 33 views
1

我想創建一個生產者/消費者與經理程序在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,3,1,2,2和3),它處理生產者'和消費者的請求 - 將一個元素放入數組(生成)或將其刪除(消耗)併發生產者和消費者在去

是否有可能在Go中創建類似此類的程序?我已經在具有發送通道的JAVA + CSP中執行此操作在生產者和消費者試圖處理相同的元素時(例如,生產者想要將1添加到管理器陣列並且同時消費者想要消耗1),管理器中的信息和警衛確定哪個過程應該首先完成, 。

Any exa mples或建議是受歡迎的,因爲我沒有找到任何有關我想做什麼的信息。如果需要,我可以給我的JAVA + CSP代碼。

UPDATE。如何同步(不從空數組中取出)?例如,如果消費者想要消耗尚未存在的管理器數組中的元素(例如,消費者想要消費'3',但管理員沒有任何這些元素),但生產者具有此元素,並且它會在少數迭代 - 我如何讓消費者一次又一次地檢查管理器陣列,直到生產者工作完成?我是否需要爲消費者元素創建結構(或類)並標記它們是否被使用,或者Go有具體方法來執行此操作?

回答

2

下面是一個完整的示例,包括通道清理。在所有消費者和生產者完成後,管理者打印結果(爲此我使用了地圖而不是分片,因爲我認爲它使代碼更容易)。

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) 
} 
+0

只需將此行'for i:= range ns'更改爲'for _,i:= range ns',並且所有內容均按預期工作,謝謝。但現在我有其他問題,如果你能看一下,我更新了我的問題。 – Eddwhis

2

我做了一個非常類似的例子,你想要做什麼,看看這個要點github gist

我實現了由一種方法是使用我的過程中消費者和企業對產生的項目我的2個過程單通道另一,for塊控制從生產者到消費者的推動,並且只要生產者不推動任何環路將會執行default。通過通道移動的對象是切片,進程將產生並消耗通過通道發送的每個切片中的標題。我相信你可以調整這個代碼來適應你的例子。

+0

謝謝你的回答和例子,我會試試! – Eddwhis

+0

祝你好運先生,如果您需要進一步的幫助,請隨時在此發表評論。 – ymg