读写共享互斥锁
Shared Mutex Read Heavy
题目详情
在量化金融中,引用数据(如标的代码映射或静态品种属性)每秒被定价组件读取百万次但极少更新。对这些读密集场景使用传统互斥锁会引入不必要的延迟。shared_mutex(读写锁)允许多个读者同时访问,写者独占更新。
任务:实现 ReadHeavyCache 类,使用 std::shared_mutex 实现读写锁。读者调用 read() 获取 shared_lock,写者调用 update() 获取 unique_lock。验证读性能显著优于普通 mutex。
英文原题
In quantitative finance, reference data such as ticker symbol mappings or static instrument properties are read millions of times per second by pricing components but updated infrequently. Utilizing a standard mutually exclusive lock for these read-heavy data structures causes severe contention and latency spikes. Implementing a Reader-Writer lock resolves this by allowing multiple threads to read concurrently while ensuring exclusive access during updates.
Task
Implement a thread-safe SymbolTa
解析
问题分析
在量化交易系统中,许多数据结构(如配置、行情快照)读操作远多于写操作。std::shared_mutex 允许多个读者并发访问,仅写入者独占。正确使用可显著降低锁竞争。
实现
template<typename T>
class ReadOptimized {
T data_;
mutable std::shared_mutex mtx_;
public:
T read() const {
std::shared_lock lk(mtx_);
return data_; // 返回值拷贝,避免持锁期间暴露引用
}
void write(const T& val) {
std::unique_lock lk(mtx_);
data_ = val;
}
template<typename F>
auto readWith(F&& f) const { // 避免拷贝:在锁内执行操作
std::shared_lock lk(mtx_);
return f(data_);
}
};复杂度与边界
- 时间复杂度:read O(1) 共享锁,write O(1) 排他锁
- 空间复杂度:O(sizeof(T))
- 边界条件:(1) 避免持锁期间调用外部回调(死锁风险)(2) write 饥饿问题:持续读流量会延迟写 (3) T 应支持拷贝或使用 readWith 避免拷贝
英文解析
Analysis
In quantitative trading systems, many data structures (configurations, market snapshots) have far more reads than writes. `std::shared_mutex` allows multiple concurrent readers with exclusive writer access. Proper usage significantly reduces lock contention.
Solution
template<typename T>
class ReadOptimized {
T data_;
mutable std::shared_mutex mtx_;
public:
T read() const {
std::shared_lock lk(mtx_);
return data_; // return value copy, avoids exposing reference while holding lock
}
void write(const T& val) {
std::unique_lock lk(mtx_);
data_ = val;
}
template<typename F>
auto readWith(F&& f) const { // avoid copy: execute operation within lock
std::shared_lock lk(mtx_);
return f(data_);
}
};Complexity & Edge Cases
- Time complexity: read O(1) shared lock; write O(1) exclusive lock
- Space complexity: O(sizeof(T))
- Edge cases: (1) Avoid calling external callbacks while holding lock (deadlock risk) (2) Write starvation: continuous read traffic delays writes (3) T should support copy or use readWith to avoid copying
Key Considerations
- Reader priority inversion: Shared mutex default favors readers — writers may starve under continuous read load; configurable writer-preference mode prevents starvation
- Upgrade deadlock: Upgrading shared_lock to unique_lock on same thread while other threads attempt same upgrade causes deadlock; require exclusive upgrade path
- Debug mode: In testing, track lock acquisition counts and hold durations; detect writer starvation (e.g., writer waiting >5s for acquisition)
- Cache line sharing: Mutex contention causes cache line bouncing between cores; pad mutex to separate cache line from protected data for optimal performance