Qt 多线程下的 UI 刷新与数据解耦
采集线程每秒产生上千条数据,直接往 UI 发信号会让主线程卡死。三种方案我们全试过。
方案一:直接跨线程信号
最简单,但每条数据一个信号,事件循环直接被淹没。1000 条/秒时界面响应延迟超过 300ms。
方案二:批量投递
采集线程本地累积 50ms 的数据,一次性发出去。信号数量降到 20 次/秒:
void Collector::flush() {
QVector<Sample> batch;
batch.swap(buffer_);
emit batchReady(batch); // 队列连接,自动跨线程
}
界面流畅了,但有个坑:QVector 跨线程传递要注册元类型,否则队列连接会静默失败。
方案三:共享缓冲区 + 定时拉取
最终采用这个。采集线程写入环形缓冲,UI 用 QTimer 每 33ms 主动拉取一次:
- 完全避免信号洪泛
- UI 刷新频率与数据产生速率解耦
- 需要无锁环形队列,或用读写锁保护
代价是延迟增加最多 33ms,对测试场景完全可接受。