This repository has been archived on 2026-05-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
obsidian/DEV/GO/Channel vs Mutex.md
T

86 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [go, golang, channel, mutex, 并发, 同步]
create time: 2026-04-24 10:30
---
# Channel vs Mutex:为什么 Go 发明了 Channel?
## 概述
Mutex 已经能做同步了,Go 为什么还要发明 Channel?本文从抽象层次、安全性、组合性等角度分析 Channel 相比 Mutex 的核心优势,以及两者的适用场景。
## 核心差异:锁"状态" vs 传递"数据"
Mutex 保护的是**共享状态(数据)**,语义是"互斥访问":拿到锁 → 读写共享变量 → 释放锁。
Channel 传递的是**数据本身(消息)**,语义是"同步地传递":发送 → 接收。数据的所有权随 channel 转移,而不是共享。
> **核心区别:Mutex 让你"共享内存",Channel 让你"传递内存"。**
## Channel 相比 Mutex 的四大优势
### 1. 数据所有权转移,比"共享访问"更安全
```go
// Mutex 模式:数据仍然在外部被共享
var data []int
mu.Lock()
data = append(data, x)
mu.Unlock()
// Channel 模式:数据随 channel 转移
ch <- x // 发送后,main goroutine 就不再持有这份数据
```
Mutex 方案下,任何持有 mu 的 goroutine 都能读写 data —— 必须在每一处都正确加锁。Channel 方案下,**数据发出去就归接收方所有**,不存在"谁在什么时候访问"的问题。
### 2. select + 多路复用:Mutex 做不到
```go
select {
case v := <-ch1:
// 处理 ch1
case v := <-ch2:
// 处理 ch2
case <-time.After(timeout):
// 超时
}
```
用 Mutex 无法实现"从多个通道中等待任意一个就绪"的模式。
### 3. 类型层面的方向约束
```go
func processor(ch <-chan int) { ... } // 只能收,不能发
func producer(ch chan<- int) { ... } // 只能发,不能收
```
在编译期就明确了数据流向。Mutex 做不到这一点 —— `*sync.Mutex` 不告诉你它保护的是哪个变量。
### 4. 同步 + 通信,一举两得
Mutex 只做同步(互斥),不传递数据。Channel 同时完成**同步**(发送阻塞到接收就绪)和**通信**(传递数据值)。
## 什么时候该用 Mutex?
Channel 不是万能药,Mutex 也有它的价值:
| 场景 | 推荐 |
|------|------|
| 保护局部共享状态(struct 多个字段被并发读写) | **Mutex** |
| 高频访问的共享计数器、缓存 | **Mutex**(性能更好) |
| goroutine 间的消息传递、管道组合 | **Channel** |
| 多路复用、超时控制、取消传播 | **Channel** |
## 两者配合使用
Channel 内部实现本身就用了 mutex 来保护缓冲区操作,说明它们是**不同抽象层次的互补工具**,而非互斥关系。实际 Go 代码中经常配合使用:
- 用 Mutex 保护 Channel 的元数据
- 用 Channel 做 goroutine 间通信,用 Mutex 保护内部共享状态
## 关联笔记
- [[DEV/GO/Channel详解]]