检查渠道的价值
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
}
我有两个用作生成器的只读通道 <-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
}