【问题标题】:At which point a routine actually blocks?在什么时候例程实际上阻塞了?
【发布时间】:2021-10-05 22:19:53
【问题描述】:

我定义了无缓冲通道并做这些

1.一次性将一些值写入其中。

2.在 main go 例程中从中读取值。

仿效

package main

import "fmt"

func main() {
    c := make(chan int)
    go func() {
        for i := 0;i < 3; i++ {
            c <- i
            fmt.Printf("write %v to channel\n", i)
        }
    }()
    for i := 0; i < 3; i++ {
        res := <-c
        fmt.Printf("read %v from channel\n", res)
    }
}

输出

write 0 to channel
read 0 from channel
read 1 from channel
write 1 to channel
write 2 to channel
read 2 from channel

我不明白排序。 在“read 0 from channel”之后,它没有被推送到channel 之后如何打印“read 1 from channel”?

我读过这样的语句,比如一旦将值推入其中,go 例程就会被阻塞,直到其他一些 go 例程从中读取值。但是在什么时候(或上面例子中的哪一行)它被阻塞了?

谁能解释一下?

【问题讨论】:

  • 写入通道并打印日志不是一项原子操作。这只是两个 fmt.Printf 之间的粗俗行为。
  • 谢谢@FerdyPruis:所以你是说输出将是每个值的读写顺序?
  • 无论如何我想了解,在上面的示例中它被阻止了哪一点? IE。就在写/读之后?
  • I do not understand the ordering 只要对 fmt 的调用未正确同步,您就不应尝试。它会是什么,取决于 cpu/go runtime/load/许多其他因素。 But at what point (or which line in above example) it gets blocked ?你的代码并没有“真正”阻塞,有一个读者和一个作者,但是,任何时候你读/写通道锁定都必须​​发生,请参阅cs.opensource.google/go/go/+/master:src/runtime/chan.go;l=235

标签: go channel goroutine


【解决方案1】:

问题出在 fmt.Printf,无法保证您的输出不会混杂。

【讨论】:

  • 谢谢@nkcode,那么您是说输出将是每个值的读写顺序吗?我想了解,在上面的示例中,哪一点被阻止了? IE。就在写/读之后?
  • 输出的顺序是未定义的,因为你不强制任何。任何一个 Go 例程都可以随时暂停以执行另一个。或者,如果多个 CPU 可用,则两者可能会同时运行。
猜你喜欢
  • 2013-02-19
  • 1970-01-01
  • 2011-09-09
  • 2019-09-04
  • 1970-01-01
  • 2013-05-28
  • 2014-02-12
  • 1970-01-01
  • 2018-05-01
相关资源
最近更新 更多