Goroutine не выполняется после отправки канала - PullRequest
0 голосов
/ 12 марта 2020
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 в этом случае.

Ответы [ 3 ]

4 голосов
/ 12 марта 2020
  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
0 голосов
/ 13 марта 2020

Мое решение для устранения проблемы:

// 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)
}

в этой строке кода hashMap[key] <- value в put функции. Он не может принять value, поскольку chan int равно nil, что это определение в параметре 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, но не саму хэш-карту.

0 голосов
/ 12 марта 2020

Кроме того, ваш код может быть уменьшен до этого. Зачем передавать параметры без необходимости! Еще одна дополнительная модификация состоит в том, что я принимаю разные значения, чтобы вы поняли концепцию более четко.

...