当前位置:网站首页>channels详细使用说明
channels详细使用说明
2022-06-21 12:00:00 【attempt_to_do】
goroutine运行在相同的地址空间,因此访问共享内存必须做好同步。那么goroutine之间如何进行数据的通信呢,Go提供了一个很好的通信机制channel。channel可以与Unix shell 中的双向管道做类比:可以通过它发送或者接收值。这些值只能是特定的类型:channel类型。定义一个channel时,也需要定义发送到channel的值的类型。注意,必须使用make 创建channel:
ci := make(chan int)
cs := make(chan string)
cf := make(chan interface{
})
channel通过操作符<-来接收和发送数据
ch <- v // 发送v到channel ch.
v := <-ch // 从ch中接收数据,并赋值给v
package main
import "fmt"
func sum(a []int, c chan int) {
total := 0
for _, v := range a {
total += v
}
c <- total // send total to c
}
func main() {
a := []int{
7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(a[:len(a)/2], c)
go sum(a[len(a)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x + y)
}
默认情况下,channel接收和发送数据都是阻塞的,除非另一端已经准备好,这样就使得Goroutines同步变的更加的简单,而不需要显式的lock。所谓阻塞,也就是如果读取(value := <-ch)它将会被阻塞,直到有数据接收。其次,任何发送(ch<-5)将会被阻塞,直到数据被读出。无缓冲channel是在多个goroutine之间同步很棒的工具。
Buffered Channels
上面我们介绍了默认的非缓存类型的channel,不过Go也允许指定channel的缓冲大小,很简单,就是channel可以存储多少元素。ch:= make(chan bool, 4),创建了可以存储4个元素的bool 型channel。在这个channel 中,前4个元素可以无阻塞的写入。当写入第5个元素时,代码将会阻塞,直到其他goroutine从channel 中读取一些元素,腾出空间。
ch := make(chan type, value)
当 value = 0 时,channel 是无缓冲阻塞读写的,当value > 0 时,channel 有缓冲、是非阻塞的,直到写满 value 个元素才阻塞写入。
Range和Close
Go通过range,像操作slice或者map一样操作缓存类型的channel。
package main
import (
"fmt"
)
func fibonacci(n int, c chan int) {
x, y := 1, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x + y
}
close(c)
}
func main() {
c := make(chan int, 10)
go fibonacci(cap(c), c)
for i := range c {
fmt.Println(i)
}
}
for i := range c能够不断的读取channel里面的数据,直到该channel被显式的关闭。上面代码我们看到可以显式的关闭channel,生产者通过内置函数close关闭channel。关闭channel之后就无法再发送任何数据了,在消费方可以通过语法v, ok := <-ch测试channel是否被关闭。如果ok返回false,那么说明channel已经没有任何数据并且已经被关闭。
Select
我们上面介绍的都是只有一个channel的情况,那么如果存在多个channel的时候,我们该如何操作呢,Go里面提供了一个关键字select,通过select可以监听channel上的数据流动。
select默认是阻塞的,只有当监听的channel中有发送或接收可以进行时才会运行,当多个channel都准备好的时候,select是随机的选择一个执行的。
package main
import "fmt"
func fibonacci(c, quit chan int) {
x, y := 1, 1
for {
select {
case c <- x:
x, y = y, x + y
case <-quit:
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit)
}
在select里面还有default语法,select其实就是类似switch的功能,default就是当监听的channel都没有准备好的时候,默认执行的(select不再阻塞等待channel)。
select {
case i := <-c:
// use i
default:
// 当c阻塞的时候执行这里
}
超时
有时候会出现goroutine阻塞的情况,那么我们如何避免整个程序进入阻塞的情况呢?我们可以利用select来设置超时,通过如下的方式实现:
func main() {
c := make(chan int)
o := make(chan bool)
go func() {
for {
select {
case v := <- c:
println(v)
case <- time.After(5 * time.Second):
println("timeout")
o <- true
break
}
}
}()
<- o
}
边栏推荐
- typora免费版,无需破解,安装直接使用
- i.MX - RT1052 SPI和 I2C接口
- [deep learning] use deep learning to monitor your girlfriend's wechat chat?
- Vs code + GCC environment compilation for STM32 development
- tensorflow中使用的一些函数
- Interesting research on mouse pointer interaction
- Factory mode implementation
- MySQL-DDL
- 知识点:PCB电路板的几种特殊布线方法
- ThinkPHP security development specification
猜你喜欢

Sdcc compiler + vscode to develop 8-bit microcontroller

Citus 11 for Postgres is completely open source and can be queried from any node (citus official blog)

马斯克的“好朋友”,冲击2022港股最大IPO

Rename all files in the folder with one click

SDCC编译器 + VSCode开发 8位微控制器

STM32开发之 VS Code + GDB下载调试

A Kuan food: the battle for "the first share of convenience food" continues

Apache ShardingSphere 5.1.2 发布|全新驱动 API + 云原生部署,打造高性能数据网关

动手学数据分析 数据重构

这3个后生,比马化腾、张一鸣还狠
随机推荐
Harmonyos training I
XML entity injection vulnerability
[Harbin Institute of technology] information sharing for the first and second examinations of postgraduate entrance examination
Typescript variable declaration - type assertion
Compilation de l'environnement vs Code + GCC développé par stm32
I would like to ask you guys, the flick CDC will add a table level exclusive lock before extracting the full amount of Oracle data
Adapter power supply automatic test equipment | introduction to charger ATE test system nsat-8000
矩形覆盖面积
STM32开发之 VS Code + gcc环境编译
Second harmonyos training
动手学数据分析 数据重构
Simulated 100 questions of 2022 safety officer-a certificate examination and online simulated examination
Vs code + GCC environment compilation for STM32 development
6-zabbix monitors and automatically discovers the memory and CPU usage of third-party Middleware
Shell process control - 35. Multi branch case conditional statements
请问各位大佬,flink cdc在抽取oracle全量数据之前会加表级排他锁
Quantitative research on heterogeneous communities 4 rate of change with bands
WPF 使用 MAUI 的自绘制逻辑
【深度学习】利用深度学习监控女朋友的微信聊天?
[untitled]