gpt4 book ai didi

go - 管理后台操作(创建/杀死)

转载 作者:行者123 更新时间:2023-12-01 22:36:26 31 4
gpt4 key购买 nike

我第一次在这里发帖,因为我在互联网上找不到干净的解决方案。

我的目标很简单,我需要创建 一个 后台操作 (goroutine 或进程或其他...)我可以 正确杀死 (不要留在后台)。

我尝试了很多事情,比如使用 chan 或 context。

但我永远找不到避免泄漏的正确方法。

这是一个例子:

package main

import (
"log"
"strconv"
"runtime"
"time"
"math/rand"
)

func main() {
log.Println("goroutines: " + strconv.Itoa(runtime.NumGoroutine()))
func1()
leak := ""
if runtime.NumGoroutine() > 1 {
leak = " there is one LEAK !!"
}
log.Println("goroutines: " + strconv.Itoa(runtime.NumGoroutine()) + leak)
}

func func1() {

done := make(chan struct{})
quit := make(chan struct{})

go func() {

log.Println("goroutines: " + strconv.Itoa(runtime.NumGoroutine()))

select {
case <-quit:
log.Println("USEFUL ???")
return
default:
func2()
done<-struct{}{}
}
}()

select {
case <-time.After(4 * time.Second):
quit<-struct{}{}
log.Println("TIMEOUT")
case <-done:
log.Println("NO TIMEOUT")
}
}

func func2() {
log.Println("JOB START")

rand.Seed(time.Now().UnixNano())
val := rand.Intn(10)
log.Println("JOB DURATION: " + strconv.Itoa(val))
time.Sleep(time.Duration(val) * time.Second) // fake a long process with an unknown duration

log.Println("JOB DONE")
}

在这个例子中,如果工作在 4 秒超时之前完成,一切都很好,goroutine 的最终数量将为 1,否则它将像我能找到的每个示例一样为 2。

但这只是一个例子,也许使用 goroutines 不可能,也许在 Go 中甚至不可能。

最佳答案

你的问题在这里:

quit := make(chan struct{})

go func() {
for {
select {
case <-quit:
log.Println("USEFUL ???")
return
default:
func2()
quit<-struct{}{}
return
}
}
}()

这个 goroutine 在 上发出信号无缓冲 channel 。这意味着当它到达 quit<-struct{}{} ,该发送将永远阻塞,因为它正在等待自己接收。不过,尚不完全清楚这是如何工作的。这里发生了一些奇怪的事情:
  • goroutine 通过 channel 向自己发送信号,这似乎是错误的 - 它不需要与自己通信
  • channel 和循环似乎没有必要; quit<-struct{}{}可以替换为 log.Println("USEFUL ???")并且可以删除整个 for/select/channel 业务
  • 该函数在每个 case 中返回的select , 所以把它放在一个循环中是没有意义的 - 没有任何场景可以让这个代码执行循环的第二次迭代
  • 关于go - 管理后台操作(创建/杀死),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61952220/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com