检查渠道的价值

Inspect value from channel

我有两个用作生成器的只读通道 <-chan Event

type Event struct{
    time int
}

我可以读出它们的值:

for {
    select {
    case <-chan1:
        // do something
    case <-chan2:
        //do something
    }

我将这些通道用于事件驱动模拟,因此我必须选择 Event 字段较少的 time

是否可以检查每个通道的值,然后才选择从哪个通道读取?因为操作 <-chan1 从 channel 中获取值并且不可能将其推回(只读 channel)。

您可以实现您的go channel 结构版本。例如下面的实现就像没有大小限制的 go 通道,你可以检查它的第一个元素。

package buffchan

import (
    "container/list"
    "sync"
)

// BufferedChannel provides go channel like interface with unlimited storage
type BufferedChannel struct {
    m *sync.Mutex
    l *list.List
    c *sync.Cond
}

// New Creates new buffer channel
func New() *BufferedChannel {
    m := new(sync.Mutex)
    return &BufferedChannel{
        m: m,
        l: list.New(),
        c: sync.NewCond(m),
    }
}

// Append adds given data at end of channel
func (b *BufferedChannel) Append(v interface{}) {
    b.m.Lock()
    defer b.m.Unlock()

    b.l.PushBack(v)
    b.c.Signal()

}

// Remove removes first element of list synchronously
func (b *BufferedChannel) Remove() interface{} {
    b.m.Lock()
    defer b.m.Unlock()

    for b.l.Len() == 0 {
        b.c.Wait()
    }

    v := b.l.Front()
    b.l.Remove(v)

    return v.Value
}

// Inspect first element of list if exists
func (b *BufferedChannel) Inspect() interface{} {
    b.m.Lock()
    defer b.m.Unlock()

    for b.l.Len() == 0 {
        return nil
    }

    return b.l.Front().Value
}

// AsyncRemove removes first element of list asynchronously
func (b *BufferedChannel) AsyncNonBlocking() interface{} {
    b.m.Lock()
    defer b.m.Unlock()

    for b.l.Len() == 0 {
        return nil
    }

    v := b.l.Front()
    b.l.Remove(v)

    return v.Value
}