Go语言并发编程指南
Go 语言的 goroutine 和 channel 让并发编程变得简单而强大。
Goroutine
go
package main
import (
"fmt"
"time"
)
func sayHello(name string) {
for i := 0; i < 3; i++ {
fmt.Printf("%s: %d
", name, i)
time.Sleep(100 * time.Millisecond)
}
}
func main() {
go sayHello("A")
go sayHello("B")
time.Sleep(time.Second)
fmt.Println("主线程结束")
}Channel
go
// 无缓冲通道:同步通信
ch := make(chan string)
go func() {
ch <- "hello" // 发送(阻塞直到有人接收)
}()
msg := <-ch // 接收
fmt.Println(msg)
// 有缓冲通道:异步通信
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
// ch <- 4 // 缓冲区满,阻塞
fmt.Println(<-ch) // 1Channel 方向
go
// 只发送通道
func producer(out chan<- int) {
for i := 0; i < 5; i++ {
out <- i
}
close(out)
}
// 只接收通道
func consumer(in <-chan int) {
for num := range in {
fmt.Println(num)
}
}
func main() {
ch := make(chan int)
go producer(ch)
consumer(ch)
}select 多路复用
go
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
ch1 <- "来自通道1"
}()
go func() {
time.Sleep(2 * time.Second)
ch2 <- "来自通道2"
}()
// 等第一个就绪的通道
select {
case msg := <-ch1:
fmt.Println(msg)
case msg := <-ch2:
fmt.Println(msg)
}
// 超时控制
select {
case msg := <-ch1:
fmt.Println(msg)
case <-time.After(500 * time.Millisecond):
fmt.Println("超时")
}
}sync.WaitGroup
go
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("任务 %d 完成
", id)
}(i)
}
wg.Wait() // 等待所有 goroutine 完成
fmt.Println("全部完成")
}Worker Pool 模式
go
func worker(id int, jobs <-chan int, results chan<- int) {
for job := range jobs {
fmt.Printf("worker %d 处理任务 %d
", id, job)
time.Sleep(time.Second)
results <- job * 2
}
}
func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)
// 启动3个worker
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// 发送5个任务
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
// 收集结果
for r := 1; r <= 5; r++ {
fmt.Println("结果:", <-results)
}
}context 超时控制
go
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("任务取消:", ctx.Err())
return
default:
fmt.Println("工作中...")
time.Sleep(500 * time.Millisecond)
}
}
}(ctx)
<-ctx.Done()
fmt.Println("主程序结束")
}总结
Go 的并发模型以 goroutine(轻量级线程)和 channel(通信管道)为核心。goroutine 创建成本低,channel 让数据安全地在 goroutine 间传递。select 实现多路复用,WaitGroup 等待任务完成,context 管理超时和取消。这套模型让并发编程既安全又高效。



评论 2