没有服务器、应用程序、脚本或二进制文件与计算机的其余部分隔离。了解幕后发生的事情很有用,因为很多事情都可能发生。

出于这个原因,Golang 提供了一种简单的方法来管理它,而无需任何黑魔法。

假设我们只有一个简单的 main 函数来启动一个简单的 http 服务器。

package main

func main{
    StartServer()
}

进入全屏模式 退出全屏模式

也许这可以正常工作,但这对底层操作系统一无所知。这意味着,如果有什么信号通知主进程停止,它只会停止或崩溃,而不会优雅地关闭服务器及其子 gorutines。

StartServer(ctx)

现在想象一下,我们可以开始一个新的例程,它知道我们感兴趣的任何信号,然后取消这个上下文。

让我们看看下面的代码,然后我们将解开它。

package main

import (
    "context"
    "log"
    "os"
    "os/signal"
)

func listenAndCancel(c chan os.Signal, cancel context.CancelFunc) {
    oscall := <-c
    log.Printf("system call:%+v", oscall)
    cancel()
}

func main(){

    // Making a channel and ctx to comunicate signInt to server
    c := make(chan os.Signal, 1)
    signal.Notify(c, os.Interrupt)
    ctx, cancel := context.WithCancel(context.Background())

    // Spawn a gorutine to cancel root context if signInt occurs
    go listenAndCancel(c, cancel)

    // Starting server with previous context
    StartServer(ctx)

}

进入全屏模式 退出全屏模式

makeos.Signals
os
signal.Notifyos.Interrupt

如果我们想更深入地了解,我们可以查看文档:

“通知使包信号将传入信号中继到 c。如果没有提供信号,所有传入的信号将被中继到 c。否则,只有提供的信号会。”

所以现在,我们已经自动化了运行时侦听中断信号的方式,然后将它们传递给通道。

StartServerlistenAndCancel

这最后一个功能是什么?简单:它接收通道和取消,然后阻塞,直到通道发出中断信号。然后它取消上下文,使服务器知道这个操作系统信号。