为了账号安全,请及时绑定邮箱和手机立即绑定

去缓冲通道(容量4)接受5而不阻塞

去缓冲通道(容量4)接受5而不阻塞

Go
Smart猫小萌 2022-06-21 16:23:10
我有 go 代码,它基本上同时运行两个 go 例程。其中一个从 (1-10) 发送 10 个 int 数字到缓冲通道“ch”(容量为 4),另一个 go 例程在for range loop  package main  import (      "fmt"      "sync"      "time"      "runtime"  )  func doSm(ch chan int, wg *sync.WaitGroup) {      defer wg.Done()      for i := 1; i <= 10; i++ {          fmt.Println("sending", i)          ch <- i          fmt.Println("sent", i)      }      close(ch)  }  func doSm2(ch chan int, wg *sync.WaitGroup) {      defer wg.Done()      time.Sleep(5 * time.Second)      for v := range ch {          fmt.Println("result:", v)      }  }  func main() {      runtime.GOMAXPROCS(1)      var wg sync.WaitGroup      ch := make(chan int, 4)      wg.Add(2)      go doSm(ch, &wg)      go doSm2(ch, &wg)      wg.Wait()  }该问题可以在下面的输出中找到。doSm() 通过 channel 发送 4 个 int 并且 go 调度程序阻塞 go 例程,直到 doSm2() 从 channel 读取这 4 个值。之后,缓冲区为空,doSm() 发送 1 个 int,doSm2() 立即读取它。现在,缓冲区再次为空,准备发送 4 个值。然而,doSm() 以某种方式发送了 5 个值(6、7、8、9、10),尽管它有容量。sending 1sent 1sending 2sent 2sending 3sent 3sending 4sent 4sending 5result: 1result: 2result: 3result: 4result: 5sent 5sending 6sent 6sending 7sent 7sending 8sent 8sending 9sent 9sending 10sent 10result: 6result: 7result: 8result: 9result: 10知道为什么会这样吗?还是我错过了什么?
查看完整描述

2 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

举例说明。


result: 5

sent 5

sending 6

sent 6

sending 7

sent 7

sending 8

sent 8

sending 9

sent 9

sending 10

sent 10

result: 6

result 5被打印,然后我们看到sent 6-7-8-9-10,然后我们看到result 6打印。这并不意味着这些值6-7-8-9-10都在通道的缓冲区中(显然它们不是)。该值6已从通道接收,但后续fmt.Println()行尚未执行。但由于6接收到,缓冲区中只有 3 个数字,因此10可以在通道上发送,如输出所示。


查看完整回答
反对 回复 2022-06-21
?
烙印99

TA贡献1829条经验 获得超13个赞

这是一个可能导致此输出的执行:

  • 发送 goroutine 发送 4 个值,并打印

  • 发送 goroutine 块

  • 接收 goroutine 接收一个值

  • 发送 goroutine 发送另一个值并打印

  • 接收 goroutine 打印

  • 接收 goroutine 接收剩余的值

通过这种交错,看起来好像发送 goroutine 发送了 5 个值。

简而言之:当涉及多个 goroutines 时,打印到 stdout 可能不会显示 goroutines 的实际交错。


查看完整回答
反对 回复 2022-06-21
  • 2 回答
  • 0 关注
  • 135 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号