最近、Golang を使用して Windows プラットフォーム用のプログラムを作成しているときに、奇妙な問題に遭遇しました。プログラムを開始した後、「Ctrl C」を押したり、コンソールを閉じたりしてもプログラムを正常に終了できません。プログラムが終了した後も、実行中のプロセスがタスク マネージャーで確認できるため、リソースが解放できなくなり、システムのパフォーマンスに重大な影響を及ぼします。多くの情報を確認した結果、最終的にプログラムが正常に終了できない原因がわかり、解決策が見つかりました。
問題の原因
Golang では、プログラムを終了する主な方法が 3 つあります。
ただし、Windows プラットフォームでは、os.Exit または os.Process.Kill メソッドを使用してプログラムを終了すると、DOS コンソールは正常に終了しません。これは、Windows プラットフォームでは、プログラムの起動時に DOS コンソールが新しいプロセス グループを作成し、プログラムの実際のプロセスと DOS コンソールのプロセスが同じプロセス グループに属さないためです。
os.Exit または os.Process.Kill メソッドを使用してプログラムを終了すると、実際のプログラムのプロセスと DOS コンソールのプロセスがそれぞれ異なるプロセス グループから終了するため、コンソールが正常に終了できなくなります。
解決策
解決策を探していたところ、システム信号を受信し、それに応じて処理する機能を提供する、パッケージ名「os/signal」の Golang 標準ライブラリを見つけました。したがって、オペレーティング システムの信号をキャプチャすることで、プログラムの正常な終了を実現できます。
「os/signal」ライブラリを使用する手順は次のとおりです:
package main import ( "fmt" "os" "os/signal" "syscall" ) func main() { fmt.Println("start program") sigs := make(chan os.Signal, 1) done := make(chan bool, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { sig := <-sigs fmt.Println() fmt.Println(sig) done <- true }() fmt.Println("waiting for signal") <-done fmt.Println("end program") os.Exit(0) }
上記のコードでは、まず signal.Notify 関数を使用して、システム割り込み信号 SIGINT とプログラム停止信号 SIGTERM を登録します。信号受信機。その後、プログラムの実行中にシグナルの受信を待ち、シグナルを受信するとシグナルの種類を出力し、受信したシグナルのステータスをパイプライン経由でメインプログラムに渡して処理します。メインプログラム。最後に、メイン プログラムがシグナルを処理した後、os.Exit(0) を使用してプログラムを通常どおり終了します。
概要
一般に、Golang は効率的でシンプルかつ安全なプログラミング言語として、システム信号を処理する際にシンプルで強力なライブラリ インターフェイスを提供します。 Windows プラットフォームでは、「os/signal」ライブラリを使用すると、プログラムが正常に終了できない問題を効果的に解決できます。ただし、オペレーティング システム環境が異なると信号の定義が異なる可能性があるため、オペレーティング システムが異なると対応する調整を行う必要があることに注意してください。同時に、信号処理プログラムを使用するときは、リソースのリークやシステムのパフォーマンスの低下を避けるために、グローバル リソースのクリーンアップと解放にも注意を払う必要があります。
以上がgolang dosが終了しないの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。