Saya menulis beberapa kod untuk mempelajari saluran go, sekeping kod seperti yang ditunjukkan di bawah:
func main(){ intChan := make(chan int, 1) strChan := make(chan string, 1) intChan <- 3 strChan <- "hello" fmt.Println("send") // comment this, fatal error: all goroutines are asleep - deadlock! // close(intChan) // close(strChan) for { select { case e, ok := <-intChan: time.Sleep(time.Second * 2) fmt.Println("The case intChan ok: ", ok) fmt.Println("The case intChan is selected.", e) case e, ok := <-strChan: time.Sleep(time.Second) fmt.Println("The case strChan ok: ", ok) fmt.Println("The case strChan is selected.", e) } } }
Jika saya mengulas fungsi close()
, pernyataan "untuk" akan menyekat, kerana ralat mengatakan "semua goroutine sedang tidur - kebuntuan!", yang nampaknya munasabah.
Jika saya membatalkan komen close()
, kenyataan "untuk" tidak pernah berhenti. Penerima mendapat nilai lalai 0 dan nol dari saluran dan tidak pernah menyekat.
Walaupun saya tidak menghantar apa-apa ke saluran dan menelefon close()
selepas menentukan saluran. Penerima tidak akan menyekat atau menyebabkan sebarang ralat.
Saya keliru tentang fungsi close
, adakah ia memulakan rutin pergi yang menghantar jenis nilai lalai tertentu ke saluran dan tidak pernah berhenti? close
函数的作用感到困惑,它是否启动一个 go 例程将特定类型的默认值发送到通道,并且永远不会停止?
当频道关闭时,您仍然可以阅读它,但您的 ok
将为 false。所以,这就是为什么你的 for
永远不会停止。并且,您需要通过条件 if !ok {break }
来中断 for
ok
anda adalah palsu. Jadi, itulah sebabnya for
anda tidak pernah berhenti. Selain itu, anda perlu memecahkan pernyataan for
dengan if !ok {break }
bersyarat.
make(chan int, 1)
Apabila saluran tidak ditutup, apabila anda cuba membaca data daripadanya, ia akan disekat atau tidak, bergantung kepada saluran buffer/tidak buffer.
make(chan int)
Saluran penimbal: Anda nyatakan saiz (
Saluran tidak buffer: Anda tidak memberikan saiz (close
的情况下,它将从您缓冲的通道读取数据一次,因为您通过 intchan <- 3
和 strchan <- "hello"
)
Dalam ulasan anda
Hantar data ke saluran. Oleh itu, anda akan melihat hasil berikut yang dicetak oleh konsol.
send the case strchan ok: true the case strchan is selected. hello the case intchan ok: true the case intchan is selected. 3
all goroutine are sleep - deadlock
Namun, selepas ini, kedua-dua saluran penimbal tidak lagi mempunyai data. Kemudian jika anda cuba membacanya anda akan disekat kerana tiada data dalam saluran buffer. (Malah, tiada penimbalan juga berlaku apabila tiada data.)
Kemudian, anda mendapat
kerana goroutine utama disekat menunggu data daripada saluran. Dengan cara ini, apabila anda menjalankan program ini, ia memulakan goroutine utama untuk menjalankan kod anda. Jika hanya satu goroutine utama disekat, ini bermakna tiada siapa yang boleh membantu anda menjalankan kod anda.Anda boleh menambah kod berikut sebelum pernyataan for. 🎜
go func() { fmt.Println("another goroutine") for {} }()
Atas ialah kandungan terperinci goroutine penerima tidak pernah menghalang apabila golang menutup saluran. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!