
php小編柚子在使用Go語言開發過程中,可能會遇到一些問題,其中之一就是在封閉的通道上發送資料時出現了問題。這個問題可能會導致通道的阻塞和程式的停滯,影響整個應用的運作。在解決這個問題之前,我們首先需要了解什麼是封閉通道,以及為什麼在封閉通道上發送資料會出現問題。接下來,我們將深入探討這個問題,並提供解決方案來修復和優化我們的Go應用程式。
問題內容
我收到一個致命錯誤:“在關閉的通道上發送”,有時我運行此程式碼,我嘗試了多種解決方案,但沒有一個有效,這是程式碼的表示,易於理解且易於使用測試:
CB14CE50B218D8EAB916B15CD95527D5
我想要的是啟動請求函數n次並獲取第一個完成的請求,然後關閉通道並且不要向通道發送更多請求,如果沒有一個請求成功完成,則等待所有goroutines完成.
我想發生這種情況是因為兩個或多個 goroutine 同時檢查通道是否關閉,並且兩個都嘗試在通道中寫入,這會導致致命錯誤。
錯誤:
1 2 3 4 5 6 | goroutine 19 [running]:
main.request(0xc00000a028, 0xc00000a030, 0x0?)
C:/test/main.go:49 +0x135
created by main.main
C:/test/main.go:17 +0xd3
panic: send on closed channel
|
登入後複製
誰能解釋為什麼會發生這種情況?
提前致謝
解決方法
問題是接收 goroutine (main
) 過早關閉 outputCh
。其他一些 goroutine 仍然可以嘗試在其上發送。
這是另一種方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
output := make(chan string)
stop := make(chan bool)
done := make(chan bool)
for i := 0; i < 20; i++ {
wg.Add(1)
go request(output, stop, &wg)
}
go func() {
wg.Wait()
done <- true
}()
firstOutput := <-output
fmt.Println( "output:" , firstOutput)
fmt.Println( "closing the stop channel" )
close(stop)
<-done
fmt.Println( "end of main" )
}
func request(output chan string, stop chan bool, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println( "request started" )
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
select {
case output <- "test" :
fmt.Println( "output sent" )
case <-stop:
fmt.Println( "stop channel is closed" )
}
}
|
登入後複製
以上是go 通道出現問題,在封閉通道上發送的詳細內容。更多資訊請關注PHP中文網其他相關文章!