我可能遗漏了一些东西,或者不了解 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 个 goroutine 为generateStuff服务,通过增加全局变量来生成数字,但requestChan似乎正在像一个障碍一样工作,以防止这种情况发生。
一般来说,我对 Go 或 Concurrency 有什么误解?
我原以为会出现两个类似generateStuff类型的 go 例程会被一起唤醒并同时增加 seq 的情况,从而导致两个消费者两次打印相同的数字。
在 playgolang 上编辑代码:http ://play.golang.org/p/eRzNXjdxtZ
收到一只叮咚
拉莫斯之舞
相关分类