我正在阅读 Go 中的并发性,并且非常接近尾声!总的来说,这是一本很棒的书。在其中一个示例中,作者正在描述如何模拟请求复制。代码示例是这样的:
func main() {
doWork := func(
done <-chan interface{},
id int,
wg *sync.WaitGroup,
result chan<- int,
) {
started := time.Now()
defer wg.Done()
// Simulate random load
simulatedLoadTime := time.Duration(1*rand.Intn(5)) * time.Second
/** use two separate select blocks because we want to send/receive two different values, the time.After (receive) and the id (send).
/ if they were in the same select block, then we could only use one value at a time, the other will get lost. */
select {
// do not want to return on <-done because we still want to log the time it took
case <-done:
case <-time.After(simulatedLoadTime):
}
select {
case <-done:
case result <- id:
}
took := time.Since(started)
// Display how long handlers would have taken
if took < simulatedLoadTime {
took = simulatedLoadTime
}
fmt.Printf("%v took %v\n", id, took)
}
done := make(chan interface{})
result := make(chan int)
var wg sync.WaitGroup
wg.Add(10)
for i := 0; i < 10; i++ {
go doWork(done, i, &wg, result)
}
firstReturned := <-result
close(done)
wg.Wait()
fmt.Printf("Received an answer from #%v\n", firstReturned)
}
我不明白的一行是case <-time.After(simulatedLoadTime). 为什么会在这里?我们什么时候使用过从该通道返回的值。该通道甚至是如何在选择块之外进行通信的?无论出于何种原因,这条线似乎在同步结果的时间方面非常重要,因为如果我用 a 替换它,default:结果就会不同步。
浮云间
相关分类