web-dev-qa-db-ja.com

アクティブなゴルーチンでプログラムを終了しても大丈夫ですか?

次のコードスニペットを取ります。

_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()は、ファイル記述子やソケット、または開いたままにしておくのが悪いものを開かないと仮定します。

18
josmith42

仕様に記載されているように 、プログラムはmain関数が完了すると終了します。

プログラムの実行は、メインパッケージを初期化してから、関数mainを呼び出すことから始まります。その関数呼び出しが戻ると、プログラムは終了します。他の(main以外の)goroutineが完了するのを待ちません。

したがって、他のゴルーチンがまだ実行されているという事実は、言語の観点からは問題ではありません。プログラムの動作によっては、まだ問題がある場合があります。

ゴルーチンがプログラム終了前にクリーンアップする必要のあるリソースを作成した場合、途中で実行を停止することが問題になる可能性があります。この場合、main関数にそれらが完了するのを最初に待機させる必要があります。 。 pthread_joinに相当するものはないため、これを自分でコーディングする必要があります(たとえば、チャネルまたはsync.WaitGroupを使用して)。

一部のリソース(ファイルを開く、ファイルロックなど)では、プロセスの終了時にオペレーティングシステムによって自動的にクリーンアップされるため、特別なクリーンアップが不要な場合があることに注意してください。

24

ゴルーチンはスレッドではなく、非常に軽量であり、実行されなくなったとき、またはプログラムが終了したときに、ランタイムが自動的にクリーンアップします。

1
OneOfOne