我可能錯過了某些東西,或不理解Go如何處理併發(或者我的併發知識),我已經設計了一些代碼來理解多個生產者/消費者。併發與多個生產者/多個消費者
這是代碼:
package main
import (
"fmt"
"time"
// "math/rand"
"sync"
)
var seq uint64 = 0
var generatorChan chan uint64
var requestChan chan uint64
func makeTimestamp() int64 {
return time.Now().UnixNano()/int64(time.Millisecond)
}
func generateStuff(genId int) {
var crap uint64
for {
crap = <-requestChan
// <- requestChan
seq = seq+1
fmt.Println("Gen ", genId, " - From : ", crap, " @", makeTimestamp())
generatorChan <- uint64(seq)
}
}
func concurrentPrint(id int, work *sync.WaitGroup) {
defer work.Done()
for i := 0; i < 5; i++ {
requestChan<-uint64(id)
fmt.Println("Conc", id, ": ", <-generatorChan)
}
}
func main() {
generatorChan = make(chan uint64)
requestChan = make(chan uint64)
var wg sync.WaitGroup
for i := 0; i < 20; i++ {
go generateStuff(i)
}
maximumWorker := 200
wg.Add(maximumWorker)
for i := 0; i < maximumWorker; i++ {
go concurrentPrint(i, &wg)
}
wg.Wait()
}
當從1運行它打印(主要是按順序)的所有數字至1000(200名消費者得到一個數每5次)。 我本來預計一些消費者會打印完全相同的號碼,但看起來請求代碼正在阻止這種情況,即使有20個goroutines服務於generateStuff,它們通過增加一個全局變量。
我在Go或Concurrency中遇到了什麼問題?
我本來預料到類似於類似的兩個去程序的情況,generateStuff會一起醒來,同時增加seq,因此有兩個消費者打印相同數字兩次。
EDIT代碼上playgolang:http://play.golang.org/p/eRzNXjdxtZ
注意,你有獲得潛在的數據賽跑到全局'seq'變量(除了未緩衝的'requestChan'可能會使它們分開)。 – 2015-04-04 20:25:20
是的,這是我所期望的戴夫,一些非確定性的行爲給我不是所有的數字從1到1000,但有些不同。 在這個例子中,chans被緩衝了http://play.golang.org/p/tq7-6Bc0hL,仍然得到相同的結果。 – Marlon 2015-04-04 20:33:19
你用'GOMAXPROCS'> 1運行了嗎? (也許使用'-race') – 2015-04-04 20:34:27