栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

关于引擎设计的一点设想

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

关于引擎设计的一点设想

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

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 
#include 

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 _cacheDataList;//数据队列

	QMutex  _mutex;//写入锁

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

数据队列管理线程:

#include 
#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 
#include 
#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 
#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下载

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/311983.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号