Created
October 22, 2019 06:08
-
-
Save ggzeng/c71df5df6f358bb4a5f65b7f69970382 to your computer and use it in GitHub Desktop.
接收channel如何优雅的退出
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1. 场景:只有一个接收通道。使用for range,如果channel关闭则会自动退出循环 | |
go func(in <-chan int) { | |
// Using for-range to exit goroutine | |
// range has the ability to detect the close/end of a channel | |
for x := range in { | |
fmt.Printf("Process %d\n", x) | |
} | |
}(inCh) | |
// 2. 场景:接收多通道,但是只要有一个通道关闭就结束。使用select ok,如果channel关闭,则ok为false | |
go func() { | |
for { // in for-select using ok to exit goroutine | |
select { | |
case x, ok := <-in: | |
if !ok { | |
return | |
} | |
fmt.Printf("Process %d\n", x) | |
processedCnt++ | |
case <-t.C: | |
fmt.Printf("Working, processedCnt = %d\n", processedCnt) | |
} | |
} | |
}() | |
// 3. 场景:接收多个通道,只有所有通道都关闭才退出。使用select ok,并把关闭的channel置为nil(这样不会被select到) | |
go func() { | |
for { // in for-select using ok to exit goroutine | |
select { | |
case x, ok := <-in1: | |
if !ok { | |
in1 = nil | |
} | |
// Process | |
case y, ok := <-in2: | |
if !ok { | |
in2 = nil | |
} | |
// Process | |
case <-t.C: | |
fmt.Printf("Working, processedCnt = %d\n", processedCnt) | |
} | |
// If both in channel are closed, goroutine exit | |
if in1 == nil && in2 == nil { | |
return | |
} | |
} | |
}() | |
// 4. 场景:有独立的退出通知通道,可以主动退出 | |
func worker(stopCh <-chan struct{}) { | |
go func() { | |
defer fmt.Println("worker exit") | |
// Using stop channel explicit exit | |
for { | |
select { | |
case <-stopCh: | |
fmt.Println("Recv stop signal") | |
return | |
case <-t.C: | |
fmt.Println("Working .") | |
} | |
} | |
}() | |
return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment