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

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

报告相同问题?

悬赏问题

  • ¥20 安装 opencv4nodejs 报错
  • ¥15 adb push异常 adb: error: 1409-byte write failed: Invalid argument
  • ¥15 nginx反向代理获取ip,java获取真实ip
  • ¥15 eda:门禁系统设计
  • ¥50 如何使用js去调用vscode-js-debugger的方法去调试网页
  • ¥15 376.1电表主站通信协议下发指令全被否认问题
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥15 复杂网络,变滞后传递熵,FDA
  • ¥20 csv格式数据集预处理及模型选择
  • ¥15 部分网页页面无法显示!