Add AsyncDbWorker: a persistent background thread with dedup queue that executes DB2 writes asynchronously, keeping the mon 20ms cycle free of blocking I/O. Changes: - async_db_worker.h/.cc: singleton worker, submit() with rule_id dedup, drain_and_stop() for clean shutdown - eqp_stat.h/.cc: new update_static(ruleid, shear_times, running_time) overload that skips redundant DB reads for known values (reduces 5 SELECTs to 3 per persist cycle) - exp_times.cc: extract persist_exp_times() as a standalone function, update_history_times() snapshots values and submits to worker (returns immediately), reset_dev_data() uses direct SHM update - eqpalg_icei.cpp: alg_mgr_.reset() → drain_and_stop() in destructor ensures all algorithm threads are stopped before draining the worker Risk: re-run cmake .. to pick up the new async_db_worker.cc file.
65 lines
1.4 KiB
C++
65 lines
1.4 KiB
C++
#include "async_db_worker.h"
|
|
|
|
AsyncDbWorker &AsyncDbWorker::instance() {
|
|
static AsyncDbWorker inst;
|
|
return inst;
|
|
}
|
|
|
|
AsyncDbWorker::AsyncDbWorker() {
|
|
worker_ = std::make_unique<std::thread>(&AsyncDbWorker::loop, this);
|
|
}
|
|
|
|
AsyncDbWorker::~AsyncDbWorker() {
|
|
if (running_) {
|
|
drain_and_stop();
|
|
}
|
|
}
|
|
|
|
void AsyncDbWorker::submit(const std::string &rule_id,
|
|
std::function<void()> task) {
|
|
{
|
|
std::lock_guard<std::mutex> guard(mtx_);
|
|
pending_[rule_id] = std::move(task); // 去重
|
|
}
|
|
cv_.notify_one();
|
|
}
|
|
|
|
void AsyncDbWorker::drain_and_stop() {
|
|
running_ = false;
|
|
cv_.notify_all();
|
|
if (worker_ && worker_->joinable()) {
|
|
worker_->join();
|
|
}
|
|
}
|
|
|
|
void AsyncDbWorker::loop() {
|
|
while (running_) {
|
|
std::function<void()> task;
|
|
{
|
|
std::unique_lock<std::mutex> lock(mtx_);
|
|
cv_.wait(lock, [this]() { return !pending_.empty() || !running_; });
|
|
if (!running_ && pending_.empty()) break;
|
|
if (!pending_.empty()) {
|
|
auto it = pending_.begin();
|
|
task = std::move(it->second);
|
|
pending_.erase(it);
|
|
}
|
|
}
|
|
if (task) {
|
|
task();
|
|
}
|
|
}
|
|
// 排空剩余任务
|
|
while (true) {
|
|
std::function<void()> task;
|
|
{
|
|
std::lock_guard<std::mutex> guard(mtx_);
|
|
if (pending_.empty()) break;
|
|
auto it = pending_.begin();
|
|
task = std::move(it->second);
|
|
pending_.erase(it);
|
|
}
|
|
if (task) task();
|
|
}
|
|
}
|