我有一個腳本,它從數據庫中選擇一些數據并將其發送到一個通道以供多個 goroutine 處理,然后將結果發送回主線程以在數據庫上更新。但是,它在將數據發送到第一個通道時掛起(可能阻塞)。頻道是在全球范圍內創建的:var chin = make(chan in)var chout = make(chan out)in并且out都是structs首先啟動goroutines:for i:=0; i<5; i++ { go worker()}加載通道的代碼是: if verbose { fmt.Println(`Getting nextbatch2 and sending to workers`) } rows, err = nextbatch2.Query() if err != nil { panic(err) } var numtodo int for rows.Next() { err = rows.Scan(&id, &data) if err != nil { rows.Close() panic(err) } // Start var vin in vin.id = id vin.data = data chin <- vin numtodo++ } rows.Close()然后緊接著: if verbose { fmt.Println(`Processing out channel from workers`) } for res := range chout { update5.Exec(res.data, res.id) if numtodo--; numtodo == 0 { break } }并且在后臺worker()運行多個goroutine:func worker() { for res := range chin { var v out v.id = res.id v.data = process(res.data) chout <- v }}此代碼在打印后掛起Getting nextbatch2 and sending to workers。它永遠不會到達Processing out channel from workers。所以它掛在rows.Next()循環內的某個地方,我無法弄清楚原因,因為chin通道應該是非阻塞的——即使worker()goroutine 沒有處理它,它仍然至少應該完成該循環。有任何想法嗎?編輯:通過fmt.Println(" on", numtodo)在rows.Next()循環末尾添加,我可以看到它在 5 之后阻塞,我不明白它應該是非阻塞的,對吧?編輯2:通過將頻道更改為make(chan in/out, 100)現在將在 105 之后阻塞。
- 1 回答
- 0 關注
- 293 瀏覽
添加回答
舉報
0/150
提交
取消