Go言語で同時実行シグナルハンドリングをどのように解決するか
Go言語では、別個のgoroutineでOSからのシグナルを監視して、そのシグナルをchannelを介してメインgoroutineに渡すことで処理できます。以下にそのサンプルコードを示します。
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
// 创建一个channel用于接收信号
signalChan := make(chan os.Signal, 1)
// 监听指定的信号,可以监听多个信号,如syscall.SIGINT和syscall.SIGTERM
signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
// 创建一个goroutine来处理接收到的信号
go func() {
// 接收到信号后,通过channel发送到主goroutine中
sig := <-signalChan
fmt.Println("接收到信号:", sig)
// 进行相应的处理,比如关闭数据库连接、保存数据等
// ...
// 退出程序
os.Exit(0)
}()
// 主goroutine继续执行其他操作
// ...
// 阻塞主goroutine,直到接收到信号
<-signalChan
}
このサンプルでは、シグナルを受信するためのチャネル signalChan を作成します。次に signal.Notify 関数を呼び出して、指定したシグナルをリッスンします。ここでは、syscall.SIGINT と syscall.SIGTERM の2つのシグナルをリッスンしています。別個のgoroutineで、<-signalChan ステートメントを使用してシグナルが来るのを待ち、シグナルを受信すると、対応する処理ロジックを実行してプログラムを終了します。
メインゴルーチンでは、ネットワークリクエストの処理や計算など、他の処理を継続して実行できます。メインゴルーチンは、シグナルを受信した場合にのみブロックされ、プログラムが終了するまでブロックされたままになります。
シグナル受信後の処理ロジックでは、全体のプログラムの進行を阻害しないよう、極力時間のかかる処理を行わないよう注意する必要があります。シグナル受信後は、必要なクリーンアップ作業を即座に行って、プログラムを正常終了させることが望ましいでしょう。