优秀的编程知识分享平台

网站首页 > 技术文章 正文

go并发最佳实践第二篇

nanyue 2024-12-01 01:43:00 技术文章 4 ℃

ch 通道在go的应用

通道是 Go 中的一种同步原语,源自 Hoare 的 CSP。虽然它们可用于同步内存访问,但它们最适合用于在 goroutine 之间传递信息,通道的默认值:nil

声明一个通道来读取和发送

stream := make(chan interface{})

声明只能读取的单向通道

stream := make(<-chan interface{})

声明只能发送的单向通道

stream := make(chan<- interface{})


不经常看到实例化通道单向,只在函数的参数中,很常见,因为 Go 将它们隐式转换

var receiveChan <-chan interface{}
var sendChan chan<- interface{}
dataStream := make(chan interface{})

// Valid statements:
receiveChan = dataStream
sendChan = dataStream

收到

<-stream


发送

stream <- "Hello world"


如果通道关闭,则在通道上测距 for range 会中断循环

intStream := make(chan int)
go func() {
    defer close(intStream) 
    for i := 1; i <= 5; i++ {
        intStream <- i
    }
}()

for integer := range intStream {
    fmt.Printf("%v ", integer)
}

无缓冲通道

无缓冲通道上的发送操作会阻塞发送 goroutine,直到另一个 goroutine 在同一通道上执行相应的接收;那时,值被传递,两个 goroutines 可以继续。

另一方面,如果事先尝试接收操作,则接收 goroutine 将被阻塞,直到另一个 goroutine 在同一通道上执行发送。通过无缓冲通道的通信使发送和接收 goroutines 同步。

因此,无缓冲通道有时被称为同步通道。当通过无缓冲通道发送值时,值的接收发生在发送 goroutine 再次唤醒之前。

在讨论并发性时,当我们说 x 发生在 y 之前时,我们不仅仅意味着 x 在时间上发生在 y 之前;我们的意思是这是有保证的,您之前的所有效果(例如变量更新)都将完成,您可以指望它们。当 x 不在 y 之前或 y 之后出现时,我们说 x 与 y 并发。这并不是说 x 和 y 一定是同时的;

buffered channel

var dataStream chan interface{}
dataStream = make(chan interface{}, 4)

读取和发送通道空导致死锁

var dataStream chan interface{}
<-dataStream // This panics with: fatal error: all goroutines are asleep - deadlock!
 goroutine 1 [chan receive (nil chan)]:
   main.main()
       /tmp/babel-23079IVB/go-src-23079O4q.go:9 +0x3f
   exit status 2
var dataStream chan interface{}
dataStream <- struct{}{} // This produces: fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send (nil chan)]:
  main.main()
      /tmp/babel-23079IVB/go-src-23079dnD.go:9 +0x77
  exit status 2

关闭通道会引起panic

var dataStream chan interface{}
close(dataStream) // This produces: panic: close of nil channel
goroutine 1 [running]:
  panic(0x45b0c0, 0xc42000a160)
      /usr/local/lib/go/src/runtime/panic.go:500 +0x1a1
  main.main()
      /tmp/babel-23079IVB/go-src-230794uu.go:9 +0x2a
  exit status 2 Yipes! This is probably

总结

操作

通道状态

结果

堵塞

_

开而不空

价值

_

打开和空

堵塞

_

默认值,假

_

只写

编译错误

堵塞

_

开放和完整

堵塞

_

开而不满

写值

_

关闭

panic

_

只接收

编译错误

panic

_

开而不空

关闭频道;读取成功直到通道被耗尽,然后读取产生默认值

_

打开和空

关闭频道;读取产生默认值

_

关闭

panic

Tags:

最近发表
标签列表