1. ホーム
  2. generics

[解決済み] golangでチャンTの満杯を監視する

2022-02-15 18:03:32

質問内容

しかし、golangコンパイラは、Tが何であれ、次のコードを受け付けません。

func monitorChan(ch chan T) {
    for {
        if len(ch) == cap(ch) {
            log.Warn("log")
        }
        time.Sleep(chanMonitorInterval)
    }
}

と表示され、エラーとなります。

は、引数のtype chan interface {}としてch (type chan []byte) を使用することができません。 を monitorChan に追加してください。

この関数はどのように修正すれば、すべてのチャンネルを1回ずつモニターするように書けるのでしょうか?


以下は私のコードです。

package main

import (
    "fmt"
    "time"
)

func monitorChan(ch chan interface{}) {
    for {
        if len(ch) == cap(ch) {
            fmt.Println("log")
        }
        time.Sleep(1 * time.Second)
    }
}

func main() {
    ch := make(chan []byte, 100)
    go monitorChan(ch)
    // actual things below ...
}

遊び場です。 https://play.golang.org/p/t7T28IpLNAs

解決方法は?

リフレクションを使用する。例えば

package main

import (
    "log"
    "reflect"
    "time"
)

func monitorChan(ch interface{}, intvl time.Duration) {
    v := reflect.ValueOf(ch)
    if v.Kind() != reflect.Chan {
        return
    }

    c := v.Cap()
    if c == 0 {
        return
    }
    for {
        if l := v.Len(); l == c {
            log.Printf("log: len(%d) cap(%d)", l, c)
        }
        time.Sleep(intvl)
    }
}

func main() {
    log.Print("main")
    c := make(chan []byte, 10)
    var chanMonitorInterval = 1 * time.Second
    go monitorChan(c, chanMonitorInterval)
    log.Print("monitor")

    time.Sleep(5 * chanMonitorInterval)
    for len(c) != cap(c) {
        c <- []byte{}
    }
    log.Print("len(c) == cap(c)")
    time.Sleep(3 * chanMonitorInterval)
    <-c
    log.Print("len(c) < cap(c)")
    time.Sleep(5 * chanMonitorInterval)
    log.Print("main")
}

遊び場です。 https://play.golang.org/p/c5VhIIO0pik

出力します。

2009/11/10 23:00:00 main
2009/11/10 23:00:00 monitor
2009/11/10 23:00:05 len(c) == cap(c)
2009/11/10 23:00:06 log: len(10) cap(10)
2009/11/10 23:00:07 log: len(10) cap(10)
2009/11/10 23:00:08 log: len(10) cap(10)
2009/11/10 23:00:08 len(c) < cap(c)
2009/11/10 23:00:13 main


参考文献

パッケージ リフレクト

囲碁ブログです。反省の法則