概要
以下、自分用のメモです。
ゴルーチン(goroutine) って、とても便利ですが、たまにリークさせてしまうことがあったりします。
基本的なパターンは決まっているのですが、見つけるのも難しいので可能な限り、そうならないように注意した方が良いですね。
個人的に一番良くやってしまうミスが今回のやつ。
処理結果によって送信側がいなくなり、受信側が放棄されてしまう
package leak import ( "errors" "github.com/devlights/gomy/output" ) // SenderAfterErrorCheck -- goroutineリークが発生するパターンのサンプルです。 // // チャネルの送受信の実装があるが、内部の処理結果によっては送信側がいなくなってしまうパターン。 // 受信側のgoroutineが永遠に待ち続けるので終了しません。 // // 解決方法としては、送信側が適切に使い終わったチャネルを閉じること。 // // REFERENCES: // - https://betterprogramming.pub/common-goroutine-leaks-that-you-should-avoid-fe12d12d6ee func SenderAfterErrorCheck() error { var ( ch = make(chan int) proc = func() bool { return false } fn = func(ch <-chan int) { data := <-ch output.Stdoutl("[recv]", data) } ) go fn(ch) if !proc() { return errors.New("this is dummy error") } // // 上でエラーが発生した場合、以下は処理されない。 // なので、上で起動しているgoroutineは永遠に受信待機することになる。 // ch <- 1 return nil }
参考情報
https://betterprogramming.pub/common-goroutine-leaks-that-you-should-avoid-fe12d12d6ee
try-golang/examples/basic/goroutines/leak at master · devlights/try-golang · GitHub
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。