协程架构重构成功, 下一步准备指针交换 无锁化重构
This commit is contained in:
@@ -1,50 +1,81 @@
|
||||
#include "asio.hpp"
|
||||
#include "Global.h"
|
||||
#include <QApplication>
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
#include "Plot_p.h"
|
||||
|
||||
namespace YSG {
|
||||
struct TimerThreadPrivate {
|
||||
asio::io_context mIoContext;
|
||||
std::unique_ptr<asio::executor_work_guard<asio::io_context::executor_type>> mWorkGuard;
|
||||
std::unique_ptr<asio::thread_pool> mCpuPool;
|
||||
std::thread::id mSchedulerThreadId;
|
||||
};
|
||||
|
||||
TimerThread::TimerThread() {
|
||||
connect(QApplication::instance(), &QApplication::aboutToQuit, [&]() {
|
||||
TimerThread::TimerThread() : d(std::make_unique<TimerThreadPrivate>()) {
|
||||
connect(QApplication::instance(), &QApplication::aboutToQuit, [this]() {
|
||||
if (isRunning()) {
|
||||
quit();
|
||||
d->mIoContext.stop();
|
||||
if(d->mCpuPool) d->mCpuPool->stop();
|
||||
wait();
|
||||
}
|
||||
delete this;
|
||||
});
|
||||
}
|
||||
TimerThread::~TimerThread() = default;
|
||||
|
||||
void TimerThread::run() {
|
||||
d->mSchedulerThreadId = std::this_thread::get_id();
|
||||
d->mIoContext.restart();
|
||||
d->mWorkGuard = std::make_unique<asio::executor_work_guard<asio::io_context::executor_type>>(d->mIoContext.get_executor());
|
||||
unsigned cpuCount = std::max(1u, std::thread::hardware_concurrency() > 1 ? std::thread::hardware_concurrency() - 1 : 1u);
|
||||
d->mCpuPool = std::make_unique<asio::thread_pool>(cpuCount);
|
||||
for (auto &plot: mPlots) {
|
||||
plot->d->mTimer = new QTimer;
|
||||
plot->d->mTimer->setTimerType(Qt::PreciseTimer);
|
||||
plot->d->mTimerThread = this;
|
||||
connect(plot->d->mTimer, &QTimer::timeout, plot, &Plot::render, Qt::DirectConnection);
|
||||
// show里的调用可能比这个 线程开启提前, 那是 timer是nullptr
|
||||
if (plot->isVisible()) plot->startRender();
|
||||
plot->d->mRenderTimer = std::make_unique<asio::steady_timer>(d->mIoContext);
|
||||
if(plot->isVisible()) plot->d->mRenderEnabled = true;
|
||||
if(plot->d->mRenderEnabled) plot->scheduleRenderTimer();
|
||||
plot->requestRender();
|
||||
}
|
||||
exec();
|
||||
d->mIoContext.run();
|
||||
for (auto &plot: mPlots) {
|
||||
plot->d->mTimer->stop();
|
||||
delete plot->d->mTimer;
|
||||
if(plot->d->mRenderTimer) {
|
||||
plot->d->mRenderTimer->cancel();
|
||||
plot->d->mRenderTimer.reset();
|
||||
}
|
||||
}
|
||||
if(d->mCpuPool) {
|
||||
d->mCpuPool->stop();
|
||||
d->mCpuPool->join();
|
||||
d->mCpuPool.reset();
|
||||
}
|
||||
d->mWorkGuard.reset();
|
||||
}
|
||||
void TimerThread::post(std::function<void()> task) {
|
||||
asio::post(d->mIoContext, std::move(task));
|
||||
}
|
||||
void TimerThread::postCpu(std::function<void()> task) {
|
||||
if(d->mCpuPool) {
|
||||
asio::post(*d->mCpuPool, std::move(task));
|
||||
} else {
|
||||
post(std::move(task));
|
||||
}
|
||||
}
|
||||
bool TimerThread::isSchedulerThread() const {
|
||||
return std::this_thread::get_id() == d->mSchedulerThreadId;
|
||||
}
|
||||
asio::io_context& TimerThread::ioContext() {
|
||||
return d->mIoContext;
|
||||
}
|
||||
|
||||
void Global::startAllTimeThread() {
|
||||
for (auto &thread: mTimerThreadMap) {
|
||||
//qDebug() << "startAllTimeThread == " << thread->objectName();
|
||||
thread->start();
|
||||
if(!thread->isRunning()) thread->start();
|
||||
}
|
||||
mTimerId = startTimer(10);
|
||||
}
|
||||
|
||||
void Global::timerEvent(QTimerEvent* event) {
|
||||
if (event->timerId() != mTimerId) return;
|
||||
for (TimerThread *t: mTimerThreadMap) {
|
||||
for (Plot *plot: t->mPlots) {
|
||||
if (plot->d->mPlotState.loadAcquire() != PlotPrivate::PlotState::NeedToPaint) continue;
|
||||
plot->repaint();
|
||||
}
|
||||
}
|
||||
Q_UNUSED(event)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user