いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-273 (ゴルーチンリークが発生するパターン (3))(処理結果によって送信側がいなくなり、受信側が放棄されてしまう)

概要

以下、自分用のメモです。

ゴルーチン(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

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。