Skip to content

go 并发

以下是 Go 并发知识点的总结表格:

并发组件描述示例
GoroutineGo 的轻量级线程,使用 go 关键字启动,管理栈大小自动化。go func() { fmt.Println("Hello") }()
ChannelGoroutine 间的通信机制,类型安全,可以是无缓冲或有缓冲通道。ch := make(chan int)
ch <- 1
val := <-ch
WaitGroup用于等待多个 Goroutine 完成任务。var wg sync.WaitGroup
wg.Add(1)
wg.Wait()
Mutex用于保护共享资源,确保同一时刻只有一个 Goroutine 可以访问。var mu sync.Mutex
mu.Lock()
mu.Unlock()
RWMutex读写锁,允许多个读操作同时进行,但写操作是独占的。var rw sync.RWMutex
rw.RLock()
rw.Unlock()
Cond条件变量,用于 Goroutine 间的等待与通知机制。cond := sync.NewCond(&sync.Mutex{})
cond.Wait()
cond.Signal()
Once确保某段代码只执行一次,通常用于初始化。var once sync.Once
once.Do(func() { fmt.Println("Run once") })
Context用于传递取消信号、超时、截止时间等信息。ctx, cancel := context.WithCancel(context.Background())
cancel()
Ticker周期性触发事件,定时器。ticker := time.NewTicker(time.Second)
for t := range ticker.C { fmt.Println(t) }
Timer一次性定时器,触发一次事件。timer := time.NewTimer(2 * time.Second)
<-timer.C
select用于监听多个通道操作,可以处理多个通道的事件。select { case val := <-ch1: fmt.Println(val) case ch2 <- 2: fmt.Println("sent") }
通道方向通道方向可明确指定为发送或接收。func send(ch chan<- int, value int) { ch <- value }
func receive(ch <-chan int) int { return <-ch }
Worker Pool限制并发执行的任务数量,通过 Goroutine 池并行处理任务。for i := 0; i < numWorkers; i++ { go worker(jobs, results) }
Pipeline数据流经多个处理步骤,使用多个 Goroutine 串联处理。in := generator(1, 2, 3, 4)
out := square(in)
for v := range out { fmt.Println(v) }
数据竞争多个 Goroutine 同时访问共享资源时需要同步,避免数据不一致。使用 sync.Mutexsync.RWMutex 来避免数据竞争。
死锁Goroutine 在等待互相持有的锁时,导致无限等待的情况。确保避免 Goroutine 之间循环依赖锁。
泄漏Goroutine 或 Channel 被阻塞或没有正确关闭时,可能会导致资源泄漏。确保关闭 Channel 或使用 defer 来确保 Goroutine 退出。
调试工具go run -race 可以检测程序中的数据竞争。go run -race main.go

此表格涵盖了 Go 中主要的并发概念,便于对比和理解每个组件的作用和使用方式。如果需要详细代码示例或更深入的讨论,请随时告诉我!