I have a function that creates a goroutine that fills a channel indefinitely, for example:
func foo() <-chan int { ch := make(chan int) go func() { defer close(ch) for { ch <- 1 } }() return ch }
Suppose we have a consumer that we want to stop after a period of time:
ch:=foo() <-ch <-ch // done
Now I want to clean up goroutine resources, including channels. I tried adding a "completion" channel for this, but then I ran into a deadlock:
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 }
Now, it seems to work, but that's only because the program exits, if I replace // here
with some io operations (for example: http.get("http://google. com")
), I'm facing a deadlock (fatal error: all goroutines are sleeping - deadlock!
).
I'm wondering if there is another way to clean up the generated goroutines and channels created by the foo
function.
Just replace default
with case
in the started goroutine:
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 }
The reasons why the original code deadlocked in the default
situation are as follows:
done
channel, goroutines initiated to write to the ch
channel will immediately go to the default
case. The goroutine will then block on line ch <- 1
until another goroutine reads the value from ch
. ch
. This results in two successful execution loops at the launched goroutine. It then tries to write done
. The goroutine started at this time may have checked the select
statement, fell into the default
situation and blocked at the ch <- 1
line. Therefore the main goroutine will also block indefinitely on the done <- true
line. This can lead to a deadlock. The above is the detailed content of Stop a goroutine that writes to a channel indefinitely. For more information, please follow other related articles on the PHP Chinese website!