如何关闭运行基于流的逻辑的 goroutine?
How to close a goroutine which runs the flow based logics?
我有一些像这样的 goroutine 逻辑:
go func() {
do_things_0()
do_things_1()
do_things_2()
do_things_3()
...
...
} ()
当服务收到请求时,它会创建这样的协程。而且 goroutine 可能会消耗内存,需要 运行 超过 30 分钟。
有时,服务可能会注意到内存不足,需要终止一些 goroutine。
我的问题是:
- 如何终止上面示例中的 goroutine?
- 有没有办法知道每个goroutine使用的内存?
更新
- 我读了其他的 SO 答案说 goroutine 不能在外面被杀死
- 我想发送信号到goroutine处理的通道让goroutine退出只适用于
for loop based logics
.
- 我正在寻找关闭
flow based logics
协程的最佳实践。
如果您 range
遍历作为您的步骤的函数列表,您应该能够轻松地将其适应 for
循环:
package main
import (
"fmt"
"time"
)
func a() { fmt.Printf("a") }
func b() { fmt.Printf("b") }
func c() { fmt.Printf("c") }
func d() { fmt.Printf("d") }
func e() { fmt.Printf("e") }
func f(quit <-chan struct{}) {
for i := 0; i < 10000; i++ {
for _, fn := range []func(){a, b, c, d, e} {
select {
case _, _ = <-quit:
fmt.Println("quit f")
return
default:
fn()
time.Sleep(1 * time.Millisecond)
}
}
}
}
func main() {
quit := make(chan struct{})
fmt.Println("go f")
go f(quit)
fmt.Println("sleep")
time.Sleep(100 * time.Millisecond)
fmt.Println("\nquit")
close(quit)
time.Sleep(10 * time.Millisecond)
fmt.Println("exit")
}
在 playground 上试用。
外部循环只是为了重复这些步骤足够长的时间,以便我们可以看到退出命令的发生。
我有一些像这样的 goroutine 逻辑:
go func() {
do_things_0()
do_things_1()
do_things_2()
do_things_3()
...
...
} ()
当服务收到请求时,它会创建这样的协程。而且 goroutine 可能会消耗内存,需要 运行 超过 30 分钟。
有时,服务可能会注意到内存不足,需要终止一些 goroutine。
我的问题是:
- 如何终止上面示例中的 goroutine?
- 有没有办法知道每个goroutine使用的内存?
更新
- 我读了其他的 SO 答案说 goroutine 不能在外面被杀死
- 我想发送信号到goroutine处理的通道让goroutine退出只适用于
for loop based logics
. - 我正在寻找关闭
flow based logics
协程的最佳实践。
如果您 range
遍历作为您的步骤的函数列表,您应该能够轻松地将其适应 for
循环:
package main
import (
"fmt"
"time"
)
func a() { fmt.Printf("a") }
func b() { fmt.Printf("b") }
func c() { fmt.Printf("c") }
func d() { fmt.Printf("d") }
func e() { fmt.Printf("e") }
func f(quit <-chan struct{}) {
for i := 0; i < 10000; i++ {
for _, fn := range []func(){a, b, c, d, e} {
select {
case _, _ = <-quit:
fmt.Println("quit f")
return
default:
fn()
time.Sleep(1 * time.Millisecond)
}
}
}
}
func main() {
quit := make(chan struct{})
fmt.Println("go f")
go f(quit)
fmt.Println("sleep")
time.Sleep(100 * time.Millisecond)
fmt.Println("\nquit")
close(quit)
time.Sleep(10 * time.Millisecond)
fmt.Println("exit")
}
在 playground 上试用。
外部循环只是为了重复这些步骤足够长的时间,以便我们可以看到退出命令的发生。