锁优化

This commit is contained in:
2026-07-23 12:27:07 +08:00
parent bd3ef5d1d5
commit 76a7053554
7 changed files with 80 additions and 136 deletions
+75 -4
View File
@@ -278,7 +278,7 @@ WaterFallRingBuffer ringBuffer
TimeAxis::mRingBuffer
SweepFrequent::mFrequents
Planisphere::dataList
Afterglow cachedPowerData / oldCachePowerData / mutexPowerData
Afterglow cachedPowerData / oldCachePowerData / mergedPowerData
Spectrum curPowers / maxPowers / minPowers / frequents
```
@@ -385,13 +385,11 @@ Input dirty 不递增 edit_state.version。
prepareData 的标准流程:
```text
lock mBufferLock
syncStatePipeline()
读取 render_state 配置
读取 render_input 增量
更新 RenderCache
clearRenderInput()
unlock mBufferLock
```
syncStatePipeline 内部同时处理:
@@ -401,6 +399,14 @@ State edit -> ready -> render
Input edit -> ready -> render
```
prepareData 不再持有 RenderData 对象级锁。
edit_state 写入必须通过 State_Edit lease。
edit_input 写入必须通过 Input_Edit lease。
RenderCache 只允许 render 流程内部更新。
prepareData 不应该写 Color。
prepareData 不应该触发 QWidget 绘制。
@@ -453,7 +459,72 @@ draw 不做输入队列交换。
把配置项放 InputData。
```
## 12. 最终规则
## 12. 锁使用边界
radio 渲染链路不允许使用 RenderData 对象级大锁。
允许存在的同步只有下面几类:
```text
Triple_Role_Buffer_Control:
使用 atomic busy / slot_state / wait / notify。
只保护物理 buffer lease 和 role 交换。
RenderPipeline:
使用 color buffer version / paintRequestPending / editStateVersion。
只保护帧发布和 Qt update 请求合并。
Plot / TimerThread:
mRenderEnabled / mDestroying / mActiveRenderTasks / pending render size 使用 atomic。
mRenderTaskMutex + mRenderTaskDone 只用于 Plot 析构等待已投递任务结束。
TimerThread::postAndWait 的局部 mutex + condition_variable 只用于跨线程同步 shutdown/removePlot。
PerformanceShower:
mMutex 只保护统计 map 和显示列表。
```
不允许重新引入:
```text
RenderData::mBufferLock
prepareData 全局锁
render size mutex
Graphic resize mutex
HoverInfo 独立 mutex
PrePareMutiDataMutex
SpinLock / SpinLockGuard
Singleton mutex + atomic 双重检查
```
prepareData 和 draw 的并发边界由调度流保证:
```text
submitRender 进入 asio scheduler。
scheduler 串行推进 jobState。
prepareData 在 scheduler 阶段消费 State/Input。
renderColor 在 CPU 阶段只读取 State_Render 和 RenderCache。
finishRender 回到 scheduler 发布 Color。
```
CPP_Core 和第三方库内部同步不属于 radio 渲染架构边界:
```text
RingBuffer_MT / StreamRingBuffer_MT:
通用多线程容器版本。
SM_RingBuffer / Cross_Process_Mutex:
跨进程共享内存同步。
Frequency_Limit:
通用频率限制器。
spdlog / asio / googlepinyin:
第三方或通用库内部同步。
```
这些同步不能向 RenderData、prepareData、draw 路径扩散。
## 13. 最终规则
```text
State 负责配置快照。
-1
View File
@@ -2,7 +2,6 @@
#define BackEnd_H
#include <QObject>
#include <QMutex>
#include <QTimer>
#include <QKeyEvent>
-55
View File
@@ -14,62 +14,7 @@
#include <QtWidgets>
#include <QtWidgetsDepends>
#include <functional>
#include "psc_global_include/Singleton.hpp"
// template <typename Derived>
// class Singleton {
// public:
// static Derived* instance() {
// Derived* temp = instance_.load(std::memory_order_acquire);
// if (temp == nullptr) {
// std::lock_guard<std::mutex> lock(mutex_);
// temp = instance_.load(std::memory_order_relaxed);
// if (temp == nullptr) {
// temp = new Derived;
// instance_.store(temp, std::memory_order_release);
// }
// }
// return temp;
// }
// Singleton(const Singleton&) = delete;
// Singleton& operator=(const Singleton&) = delete;
// protected:
// Singleton() = default;
// ~Singleton() = default;
// private:
// static std::atomic<Derived*> instance_;
// static std::mutex mutex_;
// };
// template<typename Derived>
// std::atomic<Derived*> Singleton<Derived>::instance_(nullptr);
// template<typename Derived>
// std::mutex Singleton<Derived>::mutex_;
//template<typename T>
//class Singleton {
//public:
// static T *instance() {
// if(!mInstance) {
// mInstance = new T();
// }
// return mInstance;
// }
// virtual ~Singleton() = default;
// Singleton(T &&) = delete;
// Singleton(const T &) = delete;
// void operator=(const T &) = delete;
//protected:
// Singleton() = default;
// static T* mInstance;
//};
//template<typename T> T* Singleton<T>::mInstance = nullptr;
class Global : public Psc::Singleton<Global> {
public:
explicit Global();
+2 -18
View File
@@ -1,34 +1,18 @@
#ifndef Toolbox_Singleton_H
#define Toolbox_Singleton_H
#include <mutex>
namespace Toolbox {
template<typename Derived>
class Singleton {
public:
static Derived *instance() {
Derived *temp = instance_.load(std::memory_order_acquire);
if (temp == nullptr) {
std::lock_guard<std::mutex> lock(mutex_);
temp = instance_.load(std::memory_order_relaxed);
if (temp == nullptr) {
temp = new Derived;
instance_.store(temp, std::memory_order_release);
}
}
return temp;
static Derived instance;
return &instance;
}
Singleton(const Singleton &) = delete;
Singleton &operator=(const Singleton &) = delete;
protected:
Singleton() = default;
~Singleton() = default;
private:
static std::atomic<Derived *> instance_;
static std::mutex mutex_;
};
template<typename Derived>
std::atomic<Derived *> Singleton<Derived>::instance_(nullptr);
template<typename Derived>
std::mutex Singleton<Derived>::mutex_;
}
#endif
-32
View File
@@ -1,32 +0,0 @@
#include <chrono>
#include "SpinLock.h"
namespace Toolbox {
void SpinLock::lock() {
while (flag.test_and_set(std::memory_order_acquire)) {}
}
bool SpinLock::tryLock() {
return !flag.test_and_set(std::memory_order_acquire);
}
bool SpinLock::tryLock(int durationMillis) {
if (durationMillis == 0) {
return tryLock();
}
auto duration = std::chrono::milliseconds(durationMillis);
auto start = std::chrono::steady_clock::now();
while (std::chrono::steady_clock::now() - start < duration) {
if (tryLock()) {
return true;
}
}
return false;
}
void SpinLock::unlock() {
flag.clear(std::memory_order_release);
}
SpinLockGuard::~SpinLockGuard() {
if (mLock) mLock->unlock();
}
SpinLockGuard::SpinLockGuard(SpinLock *lock) : mLock(lock) {
if (mLock) mLock->lock();
}
}
-22
View File
@@ -1,22 +0,0 @@
#ifndef Toolbox_SpinLock_H
#define Toolbox_SpinLock_H
#include <atomic>
namespace Toolbox {
class SpinLock {
public:
void lock();
bool tryLock();
bool tryLock(int durationMillis);
void unlock();
private:
std::atomic_flag flag = ATOMIC_FLAG_INIT;
};
class SpinLockGuard {
public:
explicit SpinLockGuard(SpinLock *lock);
~SpinLockGuard();
private:
SpinLock *mLock;
};
}
#endif
-1
View File
@@ -1,6 +1,5 @@
#include "Node.hpp"
#include "CircularLinkedList.hpp"
#include "SpinLock.h"
#include "Singleton.hpp"
#include "RollObject.h"
#include "SingletonWidget.hpp"