惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
博客园_首页
GbyAI
GbyAI
罗磊的独立博客
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
人人都是产品经理
人人都是产品经理
U
Unit 42
V
Visual Studio Blog
F
Fortinet All Blogs
小众软件
小众软件
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Engineering at Meta
Engineering at Meta
aimingoo的专栏
aimingoo的专栏
The Cloudflare Blog
T
Tor Project blog
Martin Fowler
Martin Fowler
K
Kaspersky official blog
Scott Helme
Scott Helme
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
D
DataBreaches.Net
博客园 - Franky
阮一峰的网络日志
阮一峰的网络日志
博客园 - 【当耐特】
P
Proofpoint News Feed
N
Netflix TechBlog - Medium
美团技术团队
S
Secure Thoughts
C
Cisco Blogs
M
MIT News - Artificial intelligence
L
Lohrmann on Cybersecurity
T
Tenable Blog
N
News and Events Feed by Topic
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Check Point Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Spread Privacy
Spread Privacy
S
Security @ Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Microsoft Security Blog
Microsoft Security Blog
A
Arctic Wolf
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Hacker News: Front Page
T
Threat Research - Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
O
OpenAI News
V
Vulnerabilities – Threatpost

卡卡罗特

最后代码 | 卡卡罗特 swagger文档 | 卡卡罗特 react脚手架开发 | 卡卡罗特 python的对象增强 | 卡卡罗特 langchain实现Agent | 卡卡罗特 03.python列表集合元组字典 | 卡卡罗特 python依赖打包 | 卡卡罗特 python的异步 | 卡卡罗特 python的生成器 | 卡卡罗特 eino整合Tools | 卡卡罗特 eino实现Agent | 卡卡罗特 eino整合RAG | 卡卡罗特 docker打包go服务 | 卡卡罗特 01-docker入门 | 卡卡罗特 docker-compose | 卡卡罗特 dockerfile | 卡卡罗特 linux安装docker | 卡卡罗特 hertz中间件 | 卡卡罗特 go整合向量数据库ChromaDB | 卡卡罗特 langchainjs | 卡卡罗特 ollama调用各大模型 | 卡卡罗特 spring-ai | 卡卡罗特 自定义一个MCP | 卡卡罗特 context.Context是什么? | 卡卡罗特 01-获取指定网站的所有的链接 | 卡卡罗特 01-Bing每日一图接口 | 卡卡罗特 02-腾讯API高清QQ头像https调用接口 | 卡卡罗特 openCV初体验 | 卡卡罗特 SyncMap的使用 | 卡卡罗特 defer的使用 | 卡卡罗特
RWMutex读写锁 | 卡卡罗特
2026-04-26 · via 卡卡罗特

鼓励作者:欢迎打赏犒劳

Demo示例

合理使用 RWMutex:

  • 写操作(initServices)使用 Lock()/Unlock()。
  • 读操作(getServices)使用 RLock()/RUnlock()。
  • 允许多个 goroutine 并发读,提高性能。

go

package main

import (
	"fmt"
	"sync"
	"time"
)

// 模拟服务依赖结构
type ServiceDeps struct {
	AppName string
	Version string
}

var (
	depsMu sync.RWMutex
	deps   *ServiceDeps // 全局共享数据,只写一次,多次读
)

// 安全读取 deps
func getServices() *ServiceDeps {
	depsMu.RLock()
	defer depsMu.RUnlock()
	return deps
}

// 初始化 deps(模拟“单线程写”)
func initServices() {
	depsMu.Lock()
	defer depsMu.Unlock()

	// Mock 数据
	deps = &ServiceDeps{
		AppName: "PriceMonitor",
		Version: "v1.0.0",
	}
	fmt.Println("✅ Services initialized!")
}

func main() {
	// 模拟应用启动:单线程初始化
	initServices()

	// 模拟多个并发请求(goroutine)同时读取
	var wg sync.WaitGroup
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()
			time.Sleep(time.Millisecond * 10) // 模拟处理延迟

			s := getServices()
			if s != nil {
				fmt.Printf("Worker %d: App=%s, Version=%s\n", id, s.AppName, s.Version)
			} else {
				fmt.Printf("Worker % d: ❌ services not ready!\n", id)
			}
		}(i)
	}

	wg.Wait()
	fmt.Println("🎉 All workers done.")
}

结果

text

✅ Services initialized!
Worker 0: App=PriceMonitor, Version=v1.0.0
Worker 3: App=PriceMonitor, Version=v1.0.0
Worker 1: App=PriceMonitor, Version=v1.0.0
Worker 4: App=PriceMonitor, Version=v1.0.0
Worker 2: App=PriceMonitor, Version=v1.0.0
🎉 All workers done.

疑问

如果不加读锁会怎么样?

我之前以为,如果是读的话则可以多个请求读?写的话则会加锁,只有一个请求操作。那么感觉读锁没啥用,是否可以不显式的加读锁呢?好像貌似也没啥问题。

但其实上,加读锁是为了防止有写的情况。

  • 多个 goroutine 可以同时读(调用 RLock())✅
  • 写操作是独占的:只要有一个 goroutine 在写(Lock()),其他读和写都必须等待 ✅
  • 读和写不能同时进行:有读时不能写,有写时不能读 ✅

这正是“读写锁”(Read-Write Mutex)的核心语义。

注意,读锁和写锁是互斥的,所以多并发读的时候还是需要加上`RLock()/RUnlock()`的,避免并发修改

什么情况下可以不加锁?

  • 只有当满足以下所有条件时,才可以无锁读:
  • 变量在程序启动时一次性初始化(比如 init() 函数中)
  • 之后永远不再修改
  • 且初始化发生在 main 执行之前(或在 main 中单线程完成)