次のコードスニペットを取ります。
_func main() {
ch := make(chan int)
quit := make(chan int)
go func() {
for {
ch <- querySomePeriodicThing()
}
}()
// ...
loop:
for {
select {
case <-ch: handlePeriodicThing()
case <-quit: break loop
}
}
}
_
ゴルーチンは、実行中実行する必要があります。 selectステートメントがquitチャネルから何かを受信すると、ループから抜け出し、プログラムはゴルーチンを停止しようとせずに終了します。
私の質問:これは、1回または2回実行しても明らかではない断続的な悪影響がありますか?他の言語では、プログラムが終了する前にスレッドをクリーンアップ(つまり終了)する必要があることを知っていますが、違いはありますか? querySomePeriodicThing()
は、ファイル記述子やソケット、または開いたままにしておくのが悪いものを開かないと仮定します。
仕様に記載されているように 、プログラムはmain
関数が完了すると終了します。
プログラムの実行は、メインパッケージを初期化してから、関数
main
を呼び出すことから始まります。その関数呼び出しが戻ると、プログラムは終了します。他の(main
以外の)goroutineが完了するのを待ちません。
したがって、他のゴルーチンがまだ実行されているという事実は、言語の観点からは問題ではありません。プログラムの動作によっては、まだ問題がある場合があります。
ゴルーチンがプログラム終了前にクリーンアップする必要のあるリソースを作成した場合、途中で実行を停止することが問題になる可能性があります。この場合、main
関数にそれらが完了するのを最初に待機させる必要があります。 。 pthread_join
に相当するものはないため、これを自分でコーディングする必要があります(たとえば、チャネルまたはsync.WaitGroup
を使用して)。
一部のリソース(ファイルを開く、ファイルロックなど)では、プロセスの終了時にオペレーティングシステムによって自動的にクリーンアップされるため、特別なクリーンアップが不要な場合があることに注意してください。
ゴルーチンはスレッドではなく、非常に軽量であり、実行されなくなったとき、またはプログラムが終了したときに、ランタイムが自動的にクリーンアップします。