Rumah >pembangunan bahagian belakang >Golang >Hentikan goroutine yang menulis ke saluran selama-lamanya
Saya mempunyai fungsi yang mencipta goroutine yang mengisi saluran selama-lamanya, contohnya:
func foo() <-chan int { ch := make(chan int) go func() { defer close(ch) for { ch <- 1 } }() return ch }
Andaikan kita mempunyai pengguna yang ingin kita hentikan selepas tempoh tertentu:
ch:=foo() <-ch <-ch // done
Sekarang saya mahu membersihkan sumber goroutine, termasuk saluran. Saya cuba menambah saluran "penyelesaian" untuk ini, tetapi kemudian saya menemui jalan buntu:
func Foo() (<-chan int, chan<- bool) { ch := make(chan int) done := make(chan bool) go func() { defer close(ch) for { select { case <-done: return default: ch <- 1 } } }() return ch, done } func main() { ch, done := Foo() <-ch <-ch done <- true // HERE }
Sekarang, ia nampaknya berfungsi, tetapi hanya kerana program keluar jika saya menggantikannya dengan beberapa operasi io // here
(例如:http.get(“http://google.com”)
) ,我面临死锁(fatal 错误:所有 goroutine 都在睡觉 - 死锁!
).
Saya tertanya-tanya sama ada terdapat cara lain untuk membersihkan goroutine dan saluran yang dihasilkan yang dibuat oleh fungsi foo
. foo
函数创建的生成的 goroutine 和通道。
只需在启动的 goroutine 中将 default
替换为 case
default
Cukup gantikan
case
dalam goroutine permulaan: func Foo() (<-chan int, chan<- bool) { ch := make(chan int) done := make(chan bool) go func() { defer close(ch) for { select { case <-done: return case ch <- 1: } } }() return ch, done }
done
通道时,启动的写入 ch
通道的 goroutines 会立即转到 default
情况。然后 goroutine 会阻塞在 ch <- 1
行,直到其他 goroutine 从 ch
adalah seperti berikut: ch
读取两次。这会导致在启动的 goroutine 处有两个成功的执行循环。然后它尝试写入 done
。此时启动的goroutine可能已经检查了select
语句,陷入default
情况并阻塞在ch <- 1
行。因此主 goroutine 也会无限期地阻塞在 done <- true
Penulisan yang dimulakan goroutine ke saluran ch
akan segera pergi ke kes selesai
. Kemudian goroutine akan menyekat pada baris ch <- 1
sehingga goroutine lain membaca nilai daripada ch
.
🎜Coroutine utama dibaca daripada ch
dua kali. Ini menghasilkan dua gelung pelaksanaan yang berjaya pada goroutine yang dilancarkan. Ia kemudian cuba menulis selesai
. Goroutine yang bermula pada masa ini mungkin telah menyemak pernyataan select
, jatuh ke dalam situasi 🎜 dan disekat pada baris ch <- 1
. Oleh itu goroutine utama juga akan menyekat selama-lamanya pada baris done <- true
. Ini boleh menyebabkan kebuntuan. 🎜
🎜Atas ialah kandungan terperinci Hentikan goroutine yang menulis ke saluran selama-lamanya. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!