英文:
Golang channel blocking operations
问题
我正在尝试停止子(或链接的)Go通道,但操作是阻塞的(例如等待网络连接的监听器)。
由于操作是阻塞的,因此在<-quit的情况下,for和case永远不会进入。
如何解决这个问题?
package main
import (
"fmt"
"time"
)
func main() {
quit := make(chan bool)
fmt.Println("Starting Channel 001")
go func() {
for {
select {
case <-quit:
fmt.Println("Channel 001 stopped")
// 期望结果:hangFunction停止执行循环
return
default:
hangFunction()
time.Sleep(1 * time.Second)
}
}
}()
time.Sleep(2 * time.Second)
fmt.Println("Closing channel 001")
close(quit)
time.Sleep(1 * time.Hour)
}
func hangFunction() {
for {
fmt.Println("[hangFunction] Looping")
time.Sleep(1 * time.Second)
}
}
请注意,我只提供了代码的翻译部分,不包括其他内容。
英文:
I'm trying to stop child (or chained) go channels, but operation is blocking (e.g listener with wait network connection)
Because operation is blocking, for and case never enter in case <-quit
How to solve this ?
package main
import (
"fmt"
"time"
)
func main() {
quit := make(chan bool)
fmt.Println("Starting Channel 001")
go func() {
for {
select {
case <-quit:
fmt.Println("Channel 001 stopped")
// Expected result: hangFunction stop execution looping
return
default:
hangFunction()
time.Sleep(1 * time.Second)
}
}
}()
time.Sleep(2 * time.Second)
fmt.Println("Closing channel 001")
close(quit)
time.Sleep(1 * time.Hour)
}
func hangFunction() {
for {
fmt.Println("[hangFunction] Looping")
time.Sleep(1 * time.Second)
}
}
答案1
得分: 1
你可以在hangFunction()
中删除for{}
循环,该循环会一直阻塞:
func hangFunction() {
fmt.Println("[hangFunction] Looping")
time.Sleep(1 * time.Second)
}
或者你可以像@Adrian在评论中提到的那样,在函数内部监视通道,做如下操作:
func hangFunction(quit chan bool) {
for {
select {
case <-quit:
return
default:
fmt.Println("[hangFunction] Looping")
time.Sleep(1 * time.Second)
}
}
}
这种方法不是很理想,因为你在主函数和函数中都有相同的select{}
块。不过它可以工作。
英文:
You can remove the for{}
loop in hangFunction()
which is blocking forever:
func hangFunction() {
fmt.Println("[hangFunction] Looping")
time.Sleep(1 * time.Second)
}
Or you can monitor the channel from within the function as @Adrian mentionned in the comments, by doing something like:
func hangFunction(quit chan bool) {
for {
select {
case <-quit:
return
default:
fmt.Println("[hangFunction] Looping")
time.Sleep(1 * time.Second)
}
}
}
which is not ideal as you have the same select{}
block twice (in your main and in the function). It will work tho.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论