Go并发
约 512 字大约 2 分钟
2025-04-07
1.Go并发
回顾下并发的定义,指一个 CPU 可以同时执行多个任务
Go实现并发基础:Goroutines 、 Channel 、Scheduler
Goroutines | Channel | Scheduler | |
---|---|---|---|
定义 | Go 中的并发执行单位,类似于轻量级的线程 | 用于 Goroutine 之间的数据传递 | 调度器会将 Goroutine 分配到系统线程中执行,并通过 系统协程(Machine) 和 P逻辑处理器(Processor)的配合高效管理并发 |
使用 | 使用 chan 关键字创建,通过 <- 操作符发送和接收数据 | ||
优点 | 非阻塞的,可以高效地运行成千上万个 Goroutine;用户无需手动分配线程 | 支持同步和数据共享,避免了显式的锁机制 |
2.Goroutine
goroutine 是 Go 中的并发执行单位,类似于轻量级的线程,
go 函数名( 参数列表 )
例如:
go f(x,y,z)
例子,使用 goroutine 以一个不同的、新创建的 goroutine 来执行一个函数
package main
import (
"fmt"
"time"
)
func sayHello() {
for i := 0; i < 5; i++ {
fmt.Println("Hello")
time.Sleep(100 * time.Millisecond)
}
}
func main() {
go sayHello() // 启动 Goroutine
for i := 0; i < 5; i++ {
fmt.Println("Main")
time.Sleep(100 * time.Millisecond)
}
}
执行结果:
Main
Hello
Main
Hello
...
3.Channel
通道(Channel)是用于 Goroutine 之间的数据传递。
使用 make
函数创建一个 channel,使用 <-
操作符发送和接收数据。如果未指定方向,则为双向通道。
ch <- v // 把 v 发送到通道 ch
v := <-ch // 从 ch 接收数据
// 并把值赋给 v
使用chan关键字声明一个通道:
ch := make(chan int)
以下实例通过两个 goroutine 来计算数字之和,在 goroutine 完成计算后,它会计算两个结果的和:
package main
import "fmt"
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // 把 sum 发送到通道 c
}
func main() {
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c // 从通道 c 中接收
fmt.Println(x, y, x+y)
}
执行结果:
-5 17 12