Go 我怎样才能杀死一只猩猩

Go 我怎样才能杀死一只猩猩,go,goroutine,Go,Goroutine,我有以下设置: func startsMain (){ go main () } fun stopMain (){ //kill main } func main() { //infinite loop } 我正在创建cumber步骤,需要能够启动和关闭应用程序。您可以使用选择和通道终止无限循环 var quit chan struct{} func startLoop() { quit := make(chan struct{}) go loo

我有以下设置:

func startsMain (){
    go main ()
}

fun stopMain (){
    //kill main
}

func main() {
    //infinite loop 
}

我正在创建cumber步骤,需要能够启动和关闭应用程序。

您可以使用
选择
和通道终止无限循环

var quit chan struct{}

func startLoop() {
    quit := make(chan struct{})
    go loop()
}

func stopLoop() {
    // As mentioned by Kaedys
    //close(quit)
    // permits signalling everyone havins such a `case <-quit:`
    // statement to be stopped at once, which might be even better.
    quit <- struct{}{}
}

// BTW, you cannot call your function main, it is reserved
func loop() {
    for {
        select {
        case <-quit:
            return # better than break
        default:
            // do stuff. I'd call a function, for clarity:
            do_stuff()
        }
    }
}

这里,
select
被阻塞,因为我们删除了
default
语句。

您不能从“外部”停止goroutine。goroutine必须支持某种终止信令(通常是一个信道)。但如果它没有,你就不能强迫它或杀死它。可能重复。你不能简单地杀死一个goroutine;请举例说明您试图解决的问题。@icza,是否可以使用goroutine以外的任何其他方式来启动和停止main?@Michael:
main
由运行时在主包中隐式调用。你不能自己调用它。我的意思是,如果你想从外部停止main(),你可以调用类似os.Exit()的东西。它通过整体关闭应用程序来关闭main,甚至可以从“main”goroutine外部调用。如果要停止主goroutine,但保持其他goroutine处于活动状态,则只能使用
runtime.Goexit()
,从主goroutine(但不一定是main()函数本身)中执行此操作,但这会产生辅助副作用(如如果所有其他goroutine也退出,则应用程序会崩溃)。值得注意的是,退出频道的典型样式是
关闭()
频道,而不是在频道上发送值。这不仅在代码中更干净,而且一个封闭的通道会同时向所有侦听器发送信号,否则您必须通过通道为每个侦听器发送单独的消息。另外,
main()
是默认调用的程序入口点,您不需要(我相信不能)将它与另一个函数分开调用。我听说了一些关于
close()
案例执行的事情,我认为这是不符合逻辑的。但是现在我明白了:立即向所有人发送信号对我来说非常有用,谢谢:)更好的是
上下文
包,请看您应该将示例更改为使用
ctx,cancel:=context.WithCancel(context.Background())
。然后,
main
可以使用
defer cancel()
,goroutines可以使用
ctx.Done()
频道上的
select
退出。但是,没有“零大小频道”这回事。所有通道在内存中的大小都相同,无论其类型如何。如果你是这个意思,它可能是无缓冲的。@JimB我想他的意思是消息本身,
struct{}{}
,是零大小的。
import "time"

// [...]

func loop() {
    // This ticker will put something in its channel every 2s 
    ticker := time.NewTicker(2 * time.Second)
    // If you don't stop it, the ticker will cause memory leaks
    defer ticker.Stop()
    for {
        select {
        case <-quit:
            return
        case <-ticker.C:
            // do stuff. I'd call a function, for clarity:
            do_stuff()
        }
    }
}