goroutine打印的切片大小和切片实际数据不一致

头像eol_tech · 提问于2021.05.28浏览量:599

问题描述:
打算使用goroutine并发执行,做了个demo测试,发现goroutine打印的切片大小和切片实际数据不一致

代码如下:

 
 
 
  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. func main() {
  7. var numsInt []int
  8. responseChannel := make(chan int, 10)
  9. go func() {
  10. for rc := range responseChannel {
  11. numsInt = append(numsInt, rc)
  12. }
  13. }()
  14. wg := &sync.WaitGroup{}
  15. for i := 0; i < 10; i++ {
  16. wg.Add(1)
  17. go func(num int, c chan int) {
  18. defer wg.Done()
  19. data := num
  20. c <- data
  21. }(i, responseChannel)
  22. }
  23. wg.Wait()
  24. // 这里打印的len(numsInt) < 10
  25. fmt.Println("len(numsInt) = ", len(numsInt))
  26. // 这里打印了10个数字
  27. fmt.Println("numsInt = ", numsInt)
  28. // 这里打印的len(numsInt) == 10
  29. fmt.Println("len(numsInt) = ", len(numsInt))
  30. }
全部回答 · 3
最新最热
  • 用户头像
    桃子2021.05.28 11:36

    通道的消费应该还没完成。在wait后加上close(responseChannel),执行会显示panic (send to closed channel)

  • 用户头像
    沙与沫2021.07.12 14:03

    你的代码里面只等待生产者往channel里面发送完毕,但没有等待消费者从channel里面消费完所有数据,当你打印numsInt的时候消费协程还在写入。当channel是带缓冲的结果会更差,因为生产者往channel里面发送数据没有阻塞,更不会跟消费者同步了。 多加一个消费者的同步代码就可以了

  • 用户头像
    热心市民鹿先生2021.07.12 14:04

    这个符合预期吧, 首先你的 channel 是带有 10 个缓存的 其次,for-loop 里面的 goroutine 是按照的预期向 channel 里面写入数据,并且 wg.Wait() 之后一定是 10 个数据都已经写入了 channel。 但是很遗憾,你没有 wait 最上面的 消费者 goroutine ,也就是说,这个时候还有可能 channel 里面有尚未消费的内容。消费的 goroutine 并没有参与到 wg 的同步逻辑里 你可以改正如下逻辑再进行一次尝试: