duangewu5234 2018-05-03 18:39
浏览 46
已采纳

如何有效地将渠道链接在一起?

I'm trying to create message hub in golang. Messages are getting through different channels that persist in map[uint32]chan []float64. I do an endless loop over map and check if a channel has a message. If it has, I write it to the common client's write channel together with an incoming channel's id. It works fine, but uses all CPU, and other processes are throttled.

UPD: Items in map adding and removing dynamically by another function.

I thinking to limit CPU for this app through Docker, but maybe there is more elegant path?

My code :

    func (c *Client) accumHandler() {

    for !c.stop {
        c.channels.Range(func(key, value interface{}) bool {

            select {
            case message := <-value.(chan []float64):
                mess := map[uint32]interface{}{key.(uint32): message}

                select {
                case c.send <- mess:

                }

            default:

            }
            return !c.stop
        })
    }
}
  • 写回答

2条回答 默认 最新

  • dongzhi1822 2018-05-03 20:02
    关注

    If I'm reading the cards correctly, it seems like you are trying to pass along an array of floats to a common channel along with a channel identifier. I assume that you are doing this to pass multiple channels out to different publishers, but so that you only have to track a single channel for your consumer.

    It turns out that you don't need to loop over channels to see when it's outputting a value. You can chain channels together inside of goroutines. For this reason, no busy wait is necessary. Something like this will suit your purposes (again, if I'm reading the cards correctly). Look for the all caps comment for the way around your busy loop. Link to playground.

    var num_publishes = 3
    
    func main() {
      num_publishers := 10
      single_consumer := make(chan []float64)
    
      for i:=0;i<num_publishers;i+=1 {
        c := make(chan []float64)
    
        // connect channel to your single consumer channel
        go func() { for { single_consumer <- <-c } }() // THIS IS PROBABLY WHAT YOU DIDN'T KNOW ABOUT
    
        // send the channel to the publisher
        go publisher(c, i*100)
      }
    
      // dumb consumer example
      for i:=0;i<num_publishers*num_publishes;i+=1 {
        fmt.Println(<-single_consumer)
      }
    }
    
    func publisher(c chan []float64, publisher_id int) {
      dummy := []float64{
        float64(publisher_id+1),
        float64(publisher_id+2),
        float64(publisher_id+3),
      }
      for i:=0;i<num_publishes;i+=1 {
        time.Sleep(time.Duration(rand.Intn(10000)) * time.Millisecond)
        c <- dummy
      }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 python变量和列表之间的相互影响
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)