猿问

你能告诉我golang通道缓冲器是如何工作的吗?

为什么剂量不工作缓冲液到右边的golang上?


如果通道已满,则等待。这是错的吗?


我不明白它是如何工作的。


你能告诉我golang通道缓冲器是如何工作的吗?


import (

    "fmt"

    "runtime"

);

func main() {

    runtime.GOMAXPROCS(1); 

    done := make(chan bool, 2); 

    count := 4;

    go func() {

        for i := 0; i < count; i++ {

            done <- true

            fmt.Println("AAAAAAAA", i);

        }

    }()

    for j := 0; j < count; j++ {

        <-done

        fmt.Println("BBBBBBBBBB", j);

    }

}


---------------------------------------------------------------------------------


AAAAAAAAAAAAAAA 0

AAAAAAAAAAAAAAA 1

AAAAAAAAAAAAAAA 2

BBBBBBBBBB 0

BBBBBBBBBB 1

BBBBBBBBBB 2

BBBBBBBBBB 3


这是我的期望


AAAAAAAAAAAAAAA 0

AAAAAAAAAAAAAAA 1

BBBBBBBBBB 0

BBBBBBBBBB 1

AAAAAAAAAAAAAAA 2

AAAAAAAAAAAAAAA 3

BBBBBBBBBB 2

BBBBBBBBBB 3


杨魅力
浏览 116回答 2
2回答

神不在的星期二

我想了解通道的解剖结构,我制作的代码几乎与您制作的代码相同。我对您的代码进行了一些小的更改func main() {&nbsp; &nbsp; runtime.GOMAXPROCS(1)&nbsp; &nbsp; done := make(chan int, 2)&nbsp; &nbsp; count := 4&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; defer close(done)&nbsp; &nbsp; &nbsp; &nbsp; for i := 0; i < count; i++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; done <- i&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("AAAAAAAA", i)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }()&nbsp; &nbsp; for j := 0; j < count; j++ {&nbsp; &nbsp; &nbsp; &nbsp; i, ok := <-done&nbsp; &nbsp; &nbsp; &nbsp; if !ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("BBBBBBBBBB", i)&nbsp; &nbsp; }&nbsp; &nbsp; time.Sleep(1 * time.Millisecond)}现在,输出将是这样的AAAAAAAA 0AAAAAAAA 1AAAAAAAA 2BBBBBBBBBB 0BBBBBBBBBB 1BBBBBBBBBB 2BBBBBBBBBB 3AAAAAAAA 3我在Cox-Buday,Katherine的并发书中发现了有关此内容的有趣信息。还值得一提的是,如果缓冲通道为空并且具有接收器,则缓冲区将被绕过,并且值将直接从发送方传递到接收器。根据这些信息,我的理解是,当我们有一个容量为2的缓冲通道时:-> main goroutine is blocked, because the channel is emptyAAAAAAAA 0 -> because, there is an active receiver this value bypassed the channelAAAAAAAA 1 -> this value is the first value in the channelAAAAAAAA 2 -> this value is the second value in the channel and channel is full now, so this goroutine is blockedBBBBBBBBBB 0 -> the main goroutine can unblock now and read the "bypassed" value-> i think the anonymous goroutine can pass the third value to channel somewhere i hereBBBBBBBBBB 1 -> the main goroutine reads the first value from the channelBBBBBBBBBB 2 -> the main goroutine reads the second value from the channelBBBBBBBBBB 3 -> the main goroutine reads the third value-> the main goroutine blocked by sleepAAAAAAAA 3 -> the anonymous goroutine can run the print statement我不是100%确定这种情况会发生,但这是我的观察。无缓冲通道也是缓冲通道,但具有 0(或 1)容量。如果您尝试使用0(无缓冲)容量的代码,这也很有趣。结果将如下所示:AAAAAAAA 0BBBBBBBBBB 0BBBBBBBBBB 1AAAAAAAA 1AAAAAAAA 2BBBBBBBBBB 2BBBBBBBBBB 3AAAAAAAA 3最后,这是我的代码。我使用缓冲区来存储结果,并仅在 main 函数的末尾将其写出到 stdout。func main() {&nbsp; &nbsp; runtime.GOMAXPROCS(1)&nbsp; &nbsp; var stdoutBuff bytes.Buffer&nbsp; &nbsp; defer stdoutBuff.WriteTo(os.Stdout)&nbsp; &nbsp; intStream := make(chan int, 0)&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; defer close(intStream)&nbsp; &nbsp; &nbsp; &nbsp; defer fmt.Fprintln(&stdoutBuff, "Producer done.")&nbsp; &nbsp; &nbsp; &nbsp; for i := 0; i < 5; i++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(&stdoutBuff, "Before Sending: %d\n", i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; intStream <- i&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(&stdoutBuff, "After Sending: %d\n", i)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }()&nbsp; &nbsp; // for integer := range intStream {&nbsp; &nbsp; //&nbsp; fmt.Fprintf(&stdoutBuff, "Received: %v\n", integer)&nbsp; &nbsp; // }&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(&stdoutBuff, "Before received.\n")&nbsp; &nbsp; &nbsp; &nbsp; v, ok := <-intStream&nbsp; &nbsp; &nbsp; &nbsp; if !ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(&stdoutBuff, "Received: %v\n", v)&nbsp; &nbsp; }}我希望它能有所帮助。

一只甜甜圈

仅当 Go 无法在下一个项目到达之前处理一个项目时,通道缓冲区才会填满。在您的情况下,没有积压的项目,因为每个项目都可以快速有效地处理。
随时随地看视频慕课网APP

相关分类

Go
我要回答