【问题标题】:Goroutine not executing after sending channel发送通道后 Goroutine 未执行
【发布时间】:2020-03-12 04:02:30
【问题描述】:
package main

import (
    "fmt"
    "sync"
)

// PUT function
func put(hashMap map[string](chan int), key string, value int, wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Printf("this is getting printed")
    hashMap[key] <- value
    fmt.Printf("this is not getting printed")
    fmt.Printf("PUT sent %d\n", value)
}

func main() {
    var value int
    var key string
    wg := &sync.WaitGroup{}
    hashMap := make(map[string](chan int), 100)
    key = "xyz"
    value = 100
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go put(hashMap, key, value, wg)
    }
    wg.Wait()
}

put 函数中的最后两个打印语句没有被打印出来,我正在尝试根据键将值放入映射中。

以及在这种情况下如何关闭 hashMap。

【问题讨论】:

标签: go semaphore channel goroutine


【解决方案1】:
  1. 您需要创建一个频道,例如hashMap[key] = make(chan int)
  2. 由于您不是从通道读取数据,因此您需要缓冲通道使其工作:
    key := "xyz"
    hashMap[key] = make(chan int, 5)

试试下面的代码:

func put(hashMap map[string](chan int), key string, value int, wg *sync.WaitGroup) {
    hashMap[key] <- value
    fmt.Printf("PUT sent %d\n", value)
    wg.Done()
}
func main() {
    var wg sync.WaitGroup
    hashMap := map[string]chan int{}
    key := "xyz"
    hashMap[key] = make(chan int, 5)
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go put(hashMap, key, 100, &wg)
    }
    wg.Wait()
}

输出:

PUT sent 100
PUT sent 100
PUT sent 100
PUT sent 100
PUT sent 100

【讨论】:

  • 在我的情况下,键可能会改变...soo 语句 1 在那里没有意义.....我想要一个包含 100 个值的哈希图,我可以在其中写入(键,值)和读取(关键)从它
  • 这个 hashMap := make(chan map[string](int), 100) 更适合我的情况吗?
  • 但这不意味着 hashMap[key] 的 5 个值的缓冲区吗?我需要一个 100 的 hashMap(即 (key1, value1)....(key100, value100))
【解决方案2】:

我的解决方法是:

// PUT function
func put(hashMap map[string](chan int), key string, value int, wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Printf("this is getting printed")
    hashMap[key] <- value // <-- nil problem
    fmt.Printf("this is not getting printed")
    fmt.Printf("PUT sent %d\n", value)
}

put函数中的hashMap[key] &lt;- value这行代码,它不能接受value,因为chan intnil,它是在put(hashMap map[string](chan int)参数中定义的。

// PUT function
func put(hashMap map[string](chan int), cval chan int, key string, value int, wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Println("this is getting printed")
    cval <- value // put the value in chan int (cval) which is initialized
    hashMap[key] = cval // set the cval(chan int) to hashMap with key
    fmt.Println("this is not getting printed")
    fmt.Printf("PUT sent %s %d\n", key, value)
}

func main() {
    var value int
    wg := &sync.WaitGroup{}

    cval := make(chan int,100)
    hashMap := make(map[string](chan int), 100)

    value = 100
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go put(hashMap, cval, fmt.Sprintf("key%d",i), value, wg)
    }
    wg.Wait()

    /* uncomment to test cval 
    close(cval)

    fmt.Println("Result:",<-hashMap["key2"])
    fmt.Println("Result:",<-hashMap["key1"])
    cval <- 88 // cannot send value to a close channel
    hashMap["key34"] = cval
    fmt.Println("Result:",<-hashMap["key1"])
    */


}

在我的代码示例中。我将cval 缓冲通道100 的大小相同初始化为hashMap,并将cval 作为put 函数中的值传递。您只能关闭 cval 而不能关闭 hashMap 本身。

【讨论】:

    【解决方案3】:

    此外,您的代码可以简化为这样。为什么不必要地传递参数!一个额外的修改是我采用不同的值来让你更清楚地理解这个概念。

    package main
    
    import (
        "log"
        "sync"
    )
    
    func put(hash chan int, wg *sync.WaitGroup) {
        defer wg.Done()
        log.Println("Put sent: ", <-hash)
    }
    
    func main() {
        hashMap := map[string]chan int{}
        key := "xyz"
        var wg sync.WaitGroup
        hashMap[key] = make(chan int, 5)
        for i := 0; i < 5; i++ {
            value := i
            wg.Add(1)
            go func(val int) {
                hashMap[key] <- val
                put(hashMap[key], &wg)
            }(value)
        }
        wg.Wait()
    }
    

    【讨论】:

    • 这显示了简化的代码,但没有解释为什么它修复了原始问题。
    猜你喜欢
    • 2018-09-29
    • 2016-03-15
    • 2013-03-20
    • 2022-08-17
    • 2017-09-20
    • 2018-06-27
    • 2018-09-11
    • 2022-11-11
    • 2014-10-10
    相关资源
    最近更新 更多