3 回答

TA貢獻1942條經驗 獲得超3個贊
您的頻道是無緩沖的(您在 make()ing 頻道時沒有指定任何緩沖區大?。?。這意味著寫入通道會阻塞,直到寫入的值被讀取。在調用 wg.Wait() 之后,您從通道讀取數據,因此不會讀取任何內容,并且您的所有 goroutine 都會卡在阻塞寫入中。
也就是說,您在這里不需要 WaitGroup。當您不知道 goroutine 何時完成時,WaitGroups 很有用,但您正在發回結果,所以您知道。這是一個示例代碼,它執行與您嘗試執行的操作類似的操作(使用偽造的工作負載)。
package main
import (
? ? "fmt"
? ? "time"
)
func main() {
? ? var procs int = 0
? ? filenames := []string{"file1", "file2", "file3", "file4"}
? ? mychan := make(chan string)
? ? for _, f := range filenames {
? ? ? ? procs += 1
? ? ? ? // worker
? ? ? ? go func(f string) {
? ? ? ? ? ? fmt.Printf("Worker processing %v\n", f)
? ? ? ? ? ? time.Sleep(time.Second)
? ? ? ? ? ? mychan <- f
? ? ? ? }(f)
? ? }
? ? for i := 0; i < procs; i++ {
? ? ? ? select {
? ? ? ? case msg := <-mychan:
? ? ? ? ? ? fmt.Printf("got %v from worker channel\n", msg)
? ? ? ? }
? ? }
}

TA貢獻1847條經驗 獲得超7個贊
雖然提出問題已經有一段時間了,但我遇到了同樣的問題。最初我的主要內容如下所示:
func main() {
filenames := make(chan string, len(os.Args))
for _, f := range os.Args[1:] {
filenames <- f
}
sizes := makeThumbnails6(filenames)
close(filenames)
log.Println("Total size: ", sizes)}
此版本死鎖,因為調用range filenames是makeThumbnails6同步的,因此close(filenames)in main 從未被調用。輸入的通道makeThumbnails6是無緩沖的,因此 goroutines 在嘗試發回大小時會阻塞。
close(filenames)解決方案是在 main 中進行函數調用之前移動。

TA貢獻1854條經驗 獲得超8個贊
代碼錯誤。簡而言之,通道sizes是無緩沖的。要修復它,我們需要在創建時使用具有足夠容量的緩沖通道sizes。一行修復就足夠了,如圖所示。這里我只是做了一個簡單的假設,1024足夠大。
func makeThumbnails6(filenames chan string) int64 {
sizes := make(chan int64, 1024) // CHANGE
var wg sync.WaitGroup // number of working goroutines
for f := range filenames {
wg.Add(1)
// worker
go func(f string) {
defer wg.Done()
thumb, err := thumbnail.ImageFile(f)
if err != nil {
log.Println(err)
return
}
info, _ := os.Stat(thumb) // OK to ignore error
fmt.Println(info.Size())
sizes <- info.Size()
}(f)
}
// closer
go func() {
wg.Wait()
close(sizes)
}()
var total int64
for size := range sizes {
total += size
}
return total
}
- 3 回答
- 0 關注
- 174 瀏覽
添加回答
舉報