2 回答

TA貢獻1827條經驗 獲得超8個贊
因為在serve()你的循環變量中使用了你在一個單獨的 goroutine 上執行的函數文字,它被運行循環的 goroutine 同時修改:數據競爭。如果您有數據競爭,則行為是未定義的。
如果您復制變量,它將起作用:
for req := range reqs {
? ? sem <- 1
? ? req2 := req
? ? go func() {
? ? ? ? process(req2)
? ? ? ? <-sem
? ? }()
}
在Go Playground上嘗試一下。
另一種可能性是將其作為參數傳遞給匿名函數:
for req := range reqs {
? ? sem <- 1
? ? go func(req *Request) {
? ? ? ? process(req)
? ? ? ? <-sem
? ? }(req)
}
在Go Playground試試這個。

TA貢獻1789條經驗 獲得超8個贊
這是因為當匿名執行時,請求已經從移動Request{0}到Request{1},所以你打印從{start 1}。
// method 1: add a parameter, pass it to anonymous function
func serve(reqs chan *Request) {
for req := range reqs {
sem <- 1
// You should make the req as parameter of this function
// or, when the function execute, the req point to Request{1}
go func(dup *Request) {
process(dup)
<-sem
}(req)
}
// And you should wait for the Request{9} to be processed
time.Sleep(time.Second)
}
// method 2: make for wait anonymous function
func serve(reqs chan *Request) {
for req := range reqs {
go func() {
process(req)
sem <- 1
}()
// Or wait here
<-sem
}
}
- 2 回答
- 0 關注
- 145 瀏覽
添加回答
舉報