发送通道后 Goroutine 不执行
Goroutine not executing after sending channel
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。
- 您需要创建一个频道,例如
hashMap[key] = make(chan int)
- 由于您不是从频道读取数据,因此您需要缓冲频道才能使其正常工作:
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
此外,您的代码可以简化为这样。为什么不必要地传递参数!一个额外的修改是我取不同的值让你更清楚地理解这个概念。
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()
}
我解决问题的方法是:
// 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] <- value
中,它不能接受 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
而不能关闭 hashMap 本身。
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。
- 您需要创建一个频道,例如
hashMap[key] = make(chan int)
- 由于您不是从频道读取数据,因此您需要缓冲频道才能使其正常工作:
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
此外,您的代码可以简化为这样。为什么不必要地传递参数!一个额外的修改是我取不同的值让你更清楚地理解这个概念。
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()
}
我解决问题的方法是:
// 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] <- value
中,它不能接受 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
而不能关闭 hashMap 本身。