windows - 队列中的老化值:Windows 计时器的最佳使用?
问题描述
我有一个包含唯一值的 std::set。我有一个保存相同值的 std::queue,以便对 std::set 中的值进行老化。
我想使用计时器来确定何时从队列中弹出一个值,然后从集合中删除该值。每次将数据添加到空集/队列时,都会创建/启动计时器。如果将数据添加到非空集合/队列中,则不会对计时器进行任何更改。计时器将每 X 毫秒触发一次以执行一个函数。该函数将从队列中弹出一个值,然后从集合中删除该值。如果集合/队列现在为空,则计时器将停止。如果 set/queue 不为空,则不更改计时器。
该程序在 Windows 10 中运行。
这种方式有意义吗?是否有更好/更有效/更简单的方法来老化数据?
我已阅读有关 Using Timer Queues 的文档,因此我了解了如何创建和销毁队列和计时器。我没有看到启动/停止计时器的建议。如果集合/队列不为空,我是否应该创建一个新的 TimerQueueTimer 以等待 X 毫秒,运行 func 然后创建一个新的 TimerQueueTimer?我是否应该创建一个 TimerQueueTimer 来定期运行 X 毫秒,但在集合/队列为空时将其删除?
我应该使用第三种技术吗?
这是我的示例代码。
using unsignedIntSet = std::set<std::uint32_t>;
using unsignedIntQ = std::queue<std::uint32_t>;
unsignedIntQ agingQ;
unsignedIntSet agingSet;
HANDLE gDoneEvent = NULL;
HANDLE hTimer = NULL;
HANDLE hTimerQueue = NULL;
VOID CALLBACK ageTimer(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
if (!agingQ.empty())
{
auto c = agingQ.front();
agingSet.erase(c);
agingQ.pop();
if (!agingQ.empty())
{
// rerun CreateTimerQueueTimer() here?
}
}
SetEvent(gDoneEvent);
}
int createTimerForAgingQ()
{
// create timer if it doesn't already exist
if (gDoneEvent == NULL)
{
gDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (gDoneEvent == NULL)
{
std::cerr << "CreateEvent() error: " << WSAGetLastError() << std::endl;
return -1;
}
hTimerQueue = CreateTimerQueue();
if (hTimerQueue == NULL)
{
std::cerr << "CreateTimerQueue() error: " << WSAGetLastError() << std::endl;
return -1;
}
if (!CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK)ageTimer, NULL, 500, 0, WT_EXECUTEONLYONCE))
{
std::cerr << "CreateTimerQueueTimer() error: " << WSAGetLastError() << std::endl;
return -1;
}
}
}
void addUnique(unsigned char* buffer, int bufferLen)
{
// hash value
auto h = hash(buffer, bufferLen);
// test insert into set
auto setResult = agingSet.emplace(h);
if (setResult.second)
{
// enqueue into historyQ
agingQ.emplace(h);
if (!gDoneEvent) createTimerForAgingQ();
}
}
解决方案
研究表明 CreateTimerQueue/CreateTimerQueueTimer 可能不是要走的路。 线程池定时器的使用
推荐阅读
- c++ - 继承构造函数并额外添加
- ios - 在 iOS 中导入文件:UIDocumentPicker 与 UIDocumentBrowser
- maven - 为什么不是
元数据添加到由 flatten-maven-plugin 生成的子 pom 文件中? - join - 雄辩的在连接子句中获取最新的原始数据
- php - 在程序 WordPress 插件中使用 WP_Session_Tokens 类
- c# - 远程调试 - 当前上下文中不存在变量
- javascript - 如何通过 DOM 访问函数?
- python - Python webscraping find_all("a") 在特定的类
- c# - 表单中的两个 HTML DATETIME 字段。结束时间/日期必须大于开始时间/日期
- java - Listview 搜索过滤结果不正确