关于引擎设计的一点设想

在仿真引擎中设计过程中比较重要的内容有时间同步控制、业务数据的流转处理。

1.时间同步

专门启动一个线程用来计时,采用C++11高精度时间库
std::chrono::high_resolution_clock::now()详见之前的文章C++中高精度时间的记录控制
在时间线程中,处理线程中不能再进行任何其他的操作,否则会影响时间的精度。

当时间间隔到达规定的时间间隔时(10ms),就会触发相应的事件,这个的触发事件就是设置变量值(每次定时器开始的时候,设置变量为false,当时间间隔到的时候设置变量为true,在变量从false到true的过程中所运行的时间就是10ms,设置完成true之后,会再次设置成false,进入下一个时间间隔循环)。

其他需要时间的线程当读取到这个变量为true时,开始执行线程中的其他代码工作(更新界面线程开始更新界面数据、生成者线程开始生产数据等)。其他的线程是如何读取到这个变量值发生了变化了呢?除了时间线程以外,其他的线程都是实时的工作状态,也就是一个“死循环”,在循环中不停的检测这个变量的值是否变为true,一旦检测到这个变量发生了变化,就会立马执行。执行完成之后,会再次等待变量变成true。

2.数据流转

数据流转模型采用的是【生产者-消费者】模型,具体模型的含义大家可以自行查找资料,这方面的资料很多。简单来说就是实体产生数据,把产生的数据放到数据队列中,消费者从数据队列中获取到数据进行出来,处理完成之后,数据队列就会删除这条数据。

单独启动一个数据队列的维护线程,这个线程的主要目的就是删除已经被处理过的数据。
在这里插入图片描述

3.实例

数据队列管理:

#pragma once
#include <queue>
#include <QMutex>

class ItemData;

//缓冲数据管理

#define CacheDataMgr() (CacheDataManager::getInstance())

class CacheDataManager {
private:
	CacheDataManager();
	static CacheDataManager* _instance;
public:
	~CacheDataManager();
	static CacheDataManager* getInstance();

	void clearInvalidData();
	void addItemData(ItemData* data);

	int dataCount();

	void setChange(bool b) {
		_isChange = b;
	}
	bool&getChange() {
		return _isChange;
	}

	ItemData* getFrontData();
private:
	std::queue<ItemData*> _cacheDataList;//数据队列

	QMutex  _mutex;//写入锁

	bool _isChange = false; //数据队列是否发生变化
};

数据队列管理线程:

#include <QDebug>
#include "DataThread.h"
#include "CacheDataManager.h"

DataThread::DataThread(QObject *parent)
	: QThread(parent) {
}

DataThread::~DataThread() {
}

void DataThread::run() {
	while (true) {
		usleep(1);
		//1.数据列表发生了变化
		if (CacheDataMgr()->getChange()) {
			qDebug() << QStringLiteral("数据队列数量:%1").arg(CacheDataMgr()->dataCount());
			CacheDataMgr()->setChange(false);
		}
		//2.清除掉无用的数据
		CacheDataMgr()->clearInvalidData();
	}
}

生成者线程:

#include <QRandomGenerator>
#include <QDebug>
#include "ProductThread.h"
#include "ItemDataString.h"
#include "ItemDataInt.h"
#include "CacheDataManager.h"

ProductThread::ProductThread( QObject *parent)
	: QThread(parent) {
}

ProductThread::~ProductThread() {
}

void ProductThread::run() {
	while (true){
		msleep(100);
		int randNum = QRandomGenerator::global()->bounded(2);//生成一个0和2之间的整数
		ItemData* itemData = nullptr;

		if (randNum%2 == 0)	{//如果是偶数
			itemData = new ItemDataInt;
			qDebug() << QStringLiteral("线程ID:%1 产生整型数据").arg(QString::number(unsigned int(QThread::currentThreadId())));
		} else {//奇数
			itemData = new ItemDataString;
			qDebug() << QStringLiteral("线程ID:%1 产生字符串数据").arg(QString::number(unsigned int(QThread::currentThreadId())));
		}

		//保存到缓存数据列表中
		CacheDataMgr()->addItemData(itemData);
	}
}

消费者线程:

#include <QDebug>
#include "ConsumeThread.h"
#include "CacheData/CacheDataManager.h"
#include "CacheData/ItemData.h"

ConsumeThread::ConsumeThread(QObject *parent)
	: QThread(parent) {
}

ConsumeThread::~ConsumeThread() {
}

void ConsumeThread::run() {
	while (true) {
		usleep(1);
		ItemData* frontData = CacheDataMgr()->getFrontData();
		if (frontData == nullptr){
			continue;
		}
		if (frontData->getValid()){
			//获取队首数据,然后处理数据
			qDebug() << QStringLiteral("消费者处理在时间%1产生的数据").arg(frontData->getDataProductTime());
			//处理完成之后,数据就变得无效
			frontData->setValid(false);
		}
	}
}

运行程序,输出结果:

"数据队列数量:1"
"消费者处理在时间2021-10-10 17:14:19.972产生的数据"
"数据队列数量:0"
"线程ID:34912 产生整型数据"
"线程ID:25076 产生整型数据"
"线程ID:1108 产生整型数据"
"数据队列数量:3"
"消费者处理在时间2021-10-10 17:14:20.082产生的数据"
"消费者处理在时间2021-10-10 17:14:20.082产生的数据"
"数据队列数量:2"
"数据队列数量:1"
"消费者处理在时间2021-10-10 17:14:20.082产生的数据"
"数据队列数量:0"
"线程ID:1108 产生整型数据"
"线程ID:34912 产生整型数据"
"线程ID:25076 产生字符串数据"
"数据队列数量:3"
"消费者处理在时间2021-10-10 17:14:20.190产生的数据"
"消费者处理在时间2021-10-10 17:14:20.190产生的数据"
"数据队列数量:2"
"消费者处理在时间2021-10-10 17:14:20.190产生的数据"
"数据队列数量:1"
"数据队列数量:0"
"线程ID:34912 产生整型数据"
"线程ID:25076 产生字符串数据"
"线程ID:1108 产生字符串数据"
"数据队列数量:3"
"消费者处理在时间2021-10-10 17:14:20.299产生的数据"
"数据队列数量:2"
"消费者处理在时间2021-10-10 17:14:20.299产生的数据"
"消费者处理在时间2021-10-10 17:14:20.299产生的数据"
"数据队列数量:1"
"数据队列数量:0"
"线程ID:1108 产生字符串数据"
"线程ID:34912 产生整型数据"
"线程ID:25076 产生字符串数据"
"数据队列数量:3"
"消费者处理在时间2021-10-10 17:14:20.408产生的数据"
"消费者处理在时间2021-10-10 17:14:20.408产生的数据"

Demo下载

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wb175208

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值