首页后端开发GOGo-并发编程-无缓冲和有缓冲 channel 的区别(二)

Go-并发编程-无缓冲和有缓冲 channel 的区别(二)

时间2023-04-27 07:24:01发布访客分类GO浏览852
导读:有缓冲 channel有缓冲 channel 是指带有一定存储空间的 channel,发送和接收操作不一定需要同步进行。当缓冲区未满时,发送操作会立即返回,并将数据存储在缓冲区中,而接收操作则会等待直到缓冲区中有数据可用。当缓冲区已满时,发...

有缓冲 channel

有缓冲 channel 是指带有一定存储空间的 channel,发送和接收操作不一定需要同步进行。当缓冲区未满时,发送操作会立即返回,并将数据存储在缓冲区中,而接收操作则会等待直到缓冲区中有数据可用。当缓冲区已满时,发送操作将被阻塞,直到缓冲区中有空闲位置可用。

以下是使用有缓冲 channel 进行通信的例子:

package main

import "fmt"

func main() {

    ch := make(chan int, 2)
    ch - 1
    ch - 2
    fmt.Println("receiving", -ch)
    fmt.Println("receiving", -ch)
}

在这个例子中,我们创建了一个带有 2 个存储空间的有缓冲 channel ch,然后向 channel 中发送了两个数值,并在主 goroutine无缓冲 channel 是指在 channel 中只能存储一个值,即该 channel 的容量为 0。如果有 goroutine 向一个未被接收的无缓冲 channel 中发送值,那么该 goroutine 会一直阻塞,直到有另一个 goroutine 从该 channel 中接收该值。这种阻塞的机制使得 goroutine 的执行是同步的,即发送和接收操作在 channel 上是同步的。

下面是一个使用无缓冲 channel 的例子:

package main

import "fmt"

func main() {

    c := make(chan int) // 创建一个无缓冲 channel

    go func() {

        fmt.Println("Start goroutine")
        c - 1 // 向 channel 发送值
        fmt.Println("End goroutine")
    }
()

    fmt.Println("Start main")
    v := -c // 从 channel 中接收值
    fmt.Println("Received", v)
    fmt.Println("End main")
}
    

输出结果为:

Start main
Start goroutine
Received 1
End main
End goroutine

在 main 函数中,先创建了一个无缓冲 channel c,并启动了一个新的 goroutine,该 goroutine 向 channel 中发送了值 1。然后,main 函数中的代码从 channel 中接收值,并将其打印出来。在这个过程中,main 函数会一直阻塞,直到从 channel 中接收到值。接着,goroutine 中的代码继续执行,将打印出 End goroutine。

由于无缓冲 channel 在发送和接收操作上是同步的,因此在这个例子中,Start goroutine 和 Start main 的输出顺序是不确定的。因为无缓冲 channel 保证了发送和接收操作的同步,所以这个例子中的输出结果是正确的,而不会出现类似数据竞争的问题。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

go

若转载请注明出处: Go-并发编程-无缓冲和有缓冲 channel 的区别(二)
本文地址: https://pptw.com/jishu/9984.html
Go-包和模块-声明和使用包(一) Go-并发编程-无缓冲和有缓冲 channel 的区别(一)

游客 回复需填写必要信息