【问题标题】:Design patterns for map channel?地图通道的设计模式?
【发布时间】:2014-01-23 15:05:04
【问题描述】:

我正在用golang写一个DNS协议解析器,想法是使用这样的映射

var tidMap map[uint16] (chan []byte)

所以对于tidMap map,key 是 tid(交易 ID),value 是一个字节数组通道。

这个想法是一个goroutine会尝试从通道中获取值,另一个goroutine会通过监听每个即将到来的数据包来尝试读取字节,一旦找到事务ID,就会将响应数据设置到tidMap,所以前一个goroutine会继续处理回应。

设计的一个问题是我需要确保通道的缓冲区长度为 1,因此可以将额外的值推入通道而不会阻塞。

那么如何在tidMap 声明中指定通道缓冲区长度?

var tidMap map[int] make(chan int, 1)

你不能在那里使用make()

【问题讨论】:

    标签: go channel goroutine


    【解决方案1】:

    通道缓冲区的长度不传达类型,因此您必须添加逻辑来测试映射条目是否存在,如果不存在:

    tidMap[0] = make(chan int, 1)
    

    【讨论】:

    • 好的,我想通了! play.golang.org/p/-zT8vLvBff 主要障碍是我在分配值时不断尝试使用<- 而不是=,因此卡住了,因为没有指定缓冲区长度的位置。
    【解决方案2】:

    简短的回答:你不能。当您make 映射时,您定义了其键和值的数据类型,并且通道的容量不是其类型的一部分。

    更长的答案是:创建一个隐藏此实现细节的抽象数据类型。像这样的:

    type ChannelMap struct {
        tidMap map[int](chan []byte)
    }
    
    func NewChannelMap() *ChannelMap { ... }
    
    func (c *ChannelMap) Put(tid int) (chan int) { 
        res := make(chan int, 1)
        c.tidMap[tid] = res
        return res
    }
    
    func (c *ChannelMap) Get(tid int) (chan int) {
        return c.tidMap[tid]
    }
    

    为了确定:给通道容量 1 并确保发送者永远不会阻塞;如果您的频道消费者太慢,生产者可以将频道填满,然后将阻塞直到频道再次有空间。

    【讨论】:

      猜你喜欢
      • 2016-06-23
      • 1970-01-01
      • 2010-11-21
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多