channel
有点类似于管道,它在goroutine
同步与通信中,有着起承转合的作用,同时也是Golang
实现CSP模型的关键
package main
func main() {
senderOnly := make(chan<- int) // 只能用来发送(管道的入口,只进不出)
receiverOnly := make(<-chan int) // 只能用来接收(管道的出口,只出不进)
unbuffer := make(chan int) // 无缓冲可收发
buffer := make(chan int, 2) // 无缓冲可收发
println(senderOnly, receiverOnly, unbuffer, buffer)
}
以下是channel
的一些使用场景
等待goroutine完成
package main
func main() {
println("start main")
ch := make(chan bool)
go func() {
println("come into goroutine")
ch <- true
}()
println("do something else")
<-ch
close(ch)
println("end main")
}
在playground中运行
打印结果:
start main
do something else
come into goroutine
end main
多个goroutine协同
三个功能不相关的goroutine
最后结果要汇总累加到result
上
package main
func main() {
println("start main")
ch := make(chan int)
var result int
go func() {
println("come into goroutine1")
var r int
for i := 1; i <= 10; i++ {
r += i
}
ch <- r
}()
go func() {
println("come into goroutine2")
var r int = 1
for i := 1; i <= 10; i++ {
r *= i
}
ch <- r
}()
go func() {
println("come into goroutine3")
ch <- 11
}()
for i := 0; i < 3; i++ {
result += <-ch
}
close(ch)
println("result is:", result)
println("end main")
}
在playground中运行
其中一组打印结果:
start main
come into goroutine3
come into goroutine2
come into goroutine1
result is: 3628866
end main
Select
两个goroutine
无直接关联,但其中一个先达到某一设定条件便退出或超时退出
package main
import "time"
func main() {
println("start main")
cond1 := make(chan int)
cond2 := make(chan uint64)
go func() {
for i := 0; ; i++ {
cond1 <- i
}
}()
go func() {
var i uint64
for ; ; i++ {
cond2 <- i
}
}()
endCond := false
for endCond != true {
select {
case a := <-cond1:
if a > 99 {
println("end with cond1")
endCond = true
}
case b := <-cond2:
if b == 100 {
println("end with cond2")
endCond = true
}
case <-time.After(time.Microsecond):
println("end with timeout")
endCond = true
}
}
println("end main")
}
在playground中运行
其中打印结果有可能是:
start main
end with cond1
end main
也有可能是:
start main
end with timeout
end main
也可能是:
start main
end with cond2
end main
这说明循环100次大概需要1微秒的时间
channel与range
package main
import "fmt"
func main() {
println("start main")
ch := make(chan int, 4)
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
// 如果不关闭channel,会引发panic
close(ch)
}()
for v := range ch {
fmt.Println(v)
}
println("end main")
}
打印结果为:
start main
0
1
2
3
4
5
6
7
8
9
end main
无缓冲channel
package main
func main() {
var ch = make(chan int)
ch <- 1
println(<-ch)
}
在playground中运行
打印结果为:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/tmp/sandbox117018544/main.go:5 +0x60
死锁了,为什么会这样呢,因为ch
是一个无缓冲的channel
,在执行到ch <- 1
就阻塞了当前goroutine
(也就是main函数所在的goroutine
),后面打印语句根本没机会执行
稍加修改即能正常运行
在playground中运行
package main
func main() {
var ch = make(chan int)
go func() {
ch <- 1
println("sender")
}()
println(<-ch)
}
因为此时ch
既有发送也有接收而且不在同一个goroutine
里面,此时它们不会相互阻塞
相关推荐
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: ...
在Golang中,channel是一个强大的特性,它允许goroutines之间的同步和通信。本文将深入探讨一些使用channel的小技巧,帮助你...通过熟练掌握这些技巧,你可以更好地利用Go语言的并发特性,编写出高效且易于维护的程序。
Go语言支持C风格的语法,同时引入了诸如goroutine(轻量级线程)和channel(通信机制)等特性,使得并发编程变得简单而高效。Go语言的垃圾回收机制则减轻了程序员管理内存的负担,增加了代码的安全性。 在《Go语言...
### Go语言协程goroutine与管道channel教程 #### 一、引言 Go语言作为一种现代编程语言,以其简洁高效的语法和强大的并发模型受到广大开发者的喜爱。其中,协程(goroutine)和管道(channel)是Go语言实现高效并发...
Go语言,又称Golang,是由Google开发的一种静态类型的、编译型的、并发型的、垃圾回收的编程语言。自2009年发布以来,Go语言因其简洁、高效的语法和强大的并发处理能力,逐渐在云计算、微服务、容器等领域获得了广泛...
然后,通过创建一个简单的Go语言应用程序——FIBONACCI数列,来展示LITEIDE的使用方法。这个示例项目包括了项目结构的建立,以及编写和运行计算斐波那契数列的代码,帮助读者实际操作,更好地理解和掌握Go语言的基本...
Go语言,也被称为Golang,是由Google开发的一种静态类型的、编译型的、并发型的、垃圾回收的、强类型的语言。它以其内置的并发原语而著名,这些原语使得编写能够充分利用多核处理器的程序变得简单。在Go语言中,`...
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: ...
1. **并发处理**: Go语言的goroutine和channel机制使得编写并发程序变得简单。goroutine是轻量级线程,可以高效地运行大量并发任务,而channel则提供了安全的数据通信方式,避免了多线程环境下的数据竞争问题。 2. ...
2. **并发模型**:Go语言内置了goroutine和channel,它们提供了一种轻量级的线程实现,使得编写高并发程序变得简单。goroutine是协程,其开销小,可以大量并发运行,而channel则用于goroutine之间的通信,实现数据...
2. **并发支持**:Go语言内置goroutine和channel,使得并发编程变得极其简单。 3. **垃圾回收**:Go语言有自动的内存管理机制,无需程序员手动进行内存分配和释放。 4. **静态链接**:Go编译出的可执行文件包含所有...
- **简洁性**:Go语言语法简单明了,易于学习。 - **高效性**:Go语言编译速度快,执行效率高。 - **并发支持**:Go通过goroutine和channel机制提供内置的并发支持,简化了并发编程的复杂度。 - **环境影响因素*...
channel[通道]是golang的一种重要特性,正是因为channel的存在才使得golang不同于其它语言。channel使得并发编程变得简单容易有趣。 channel的概念和语法 一个channel可以理解为一个先进先出的消息队列。channel用来...
Go语言是一种开源编程语言,具有简单易学、高性能、跨平台等特性,目前已经成为构建高效、可靠的应用程序的重要选择。Go语言在计算机编程领域的重要性不断提升,特别是在云平台、分布式系统和并发处理等领域。为了...
Go 语言中的 channel 是实现 goroutine 间无锁通信的关键机制,他使得写多线程并发程序变得简单、灵活、触手可得。下面就个人理解对 channel 使用过程中应该注意的地方进行一个简要的总结。
理解如何正确地使用goroutine和channel是提升Go语言编程能力的关键。 2. **接口(Interface)**:Go语言的接口设计十分灵活,它是一种动态类型检查机制。通过接口,我们可以实现多态性,编写出更加通用和可复用的...
- **并发模型**:深入理解Go语言的并发模型,包括goroutine和channel的使用技巧。 - **内存管理**:探讨Go语言中的垃圾回收机制及其对性能的影响。 - **错误处理**:介绍Go语言特有的错误处理方式,如使用error类型...
1. 并发原生支持:Go语言通过goroutine和channel实现了轻量级线程,使得并发编程变得简单高效。 2. 垃圾回收(GC):Go语言内建了垃圾回收机制,自动管理内存,减轻了程序员的工作负担。 3. 动态和静态的结合:虽然...