dongzhang6021 2018-05-22 00:48
浏览 54
已采纳

如何通过go例程连接多个切片

New to go. I am trying to read a map[int][]string, write the slice of strings into an intermediate channel and then once everything is written, read back all the strings from intermediate channel to another channel and finally read the channel into another goroutine.

I am not able to figure out what is a good non-blocking way to read from the intermediate channel.

package main

import (
    "fmt"
)

func f1(c chan []string, q chan int) {
  // intermediate channel
    ic := make(chan []string, 10)

  hmap := map[int][]string{
    0: []string{"a", "b", "c"},
    1: []string{"d", "e",},
    2: []string{"f", "g", "h"},
  }
  // for every elem in hmap put the values into intermediate channel
    for _, v := range hmap {
       f2(v, ic)
    }

  // everything is in intermediate channel by now
  // read all the []string and concatenate them into a slice in a
  // non-blocking fashion
  var strs []string
  for v := range ic {
    strs = append(strs, v...)
  }
    // strs := <-ic
  fmt.Println(strs)
    select {
  case c <- strs:
    fmt.Println("Received strings.")
  default:
    fmt.Println("did not receive anything.")
  }
    q <- 1
}

func f2(v []string, ic chan []string) {
    select {
    case ic <- v:
        fmt.Println("Sent to intermediate channel:", v)
    default:
        fmt.Println("nothing to send...")
    }
}
func f3(c chan []string) {
    fmt.Println(<-c)
}

func main() {
    c := make(chan []string, 10)
    q := make(chan int)
    go f1(c, q)
    go f3(c)
    fmt.Println(<-q) // to wait for the quit to be set
}

go run main.go to run.

This program goes into deadlock. How can I avoid the deadlock?

  • 写回答

1条回答 默认 最新

  • 普通网友 2018-05-22 01:55
    关注

    As @zerkms said in the comment, you need to close the channel when you're done writing to it, or the for v := range ic { will block.

    package main
    
    import (
        "fmt"
    )
    
    func f1(c chan []string, q chan int) {
        ic := make(chan []string, 10)
    
        hmap := map[int][]string{
            0: []string{"a", "b", "c"},
            1: []string{"d", "e"},
            2: []string{"f", "g", "h"},
        }
        for _, v := range hmap {
            f2(v, ic)
        }
        // done writing strings, close the channel
        close(ic)
        var strs []string
        for v := range ic {
            strs = append(strs, v...)
        }
        fmt.Println(strs)
        select {
        case c <- strs:
            fmt.Println("Received strings.")
        default:
            fmt.Println("did not receive anything.")
        }
        q <- 1
    }
    
    func f2(v []string, ic chan []string) {
        select {
        case ic <- v:
            fmt.Println("Sent to intermediate channel:", v)
        default:
            fmt.Println("nothing to send...")
        }
    }
    func f3(c chan []string) {
        fmt.Println(<-c)
    }
    
    func main() {
        c := make(chan []string, 10)
        q := make(chan int)
        go f1(c, q)
        go f3(c)
        fmt.Println(<-q) // to wait for the quit to be set
    }
    

    https://play.golang.org/p/qZoAElTlkAa

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 echarts动画效果失效的问题。官网下载的例子。
  • ¥60 许可证msc licensing软件报错显示已有相同版本软件,但是下一步显示无法读取日志目录。
  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥30 关于<main>标签页面跳转的问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加