具有可变周期的WaitableTimer
WaitableTimer with variable period
本文关键字:WaitableTimer 周期 更新时间:2023-10-16
我需要设置一个周期性执行的可等待计时器。
问题如下,周期每X个周期(比如说5个周期)变化一次,这取决于系统在最后5个周期执行任务所花费的时间。
我尝试使用一个自动重置等待计时器,它在每次迭代后都会被设置(5次中有4次间隔相同)。然而,时间与我设置的内容无关。相关代码如下所示。(一切都从调用HandleSensor开始)
float AnalysisClient::GetNewInterval()
{
...
return newInterval;
}
VOID CALLBACK AnalysisClient::TimerFinished(LPVOID lpArg,
DWORD dwTimerLowValue,
DWORD dwTimerHighValue)
{
LARGE_INTEGER t;
AnalysisClient* This = (AnalysisClient*)lpArg;
This->readsensor();
t.QuadPart = GetNewInterval() * 10000i64;
SetWaitableTimer(_sensorTimer, &t, 0, TimerFinished, This, TRUE);
}
void AnalysisClient::WaitForsensor()
{
LARGE_INTEGER t;
t.QuadPart = 0;
SetWaitableTimer(_sensorTimer, &t, 0, TimerFinished, this, TRUE);
SleepEx(
INFINITE, // Wait forever.
TRUE);
}
void AnalysisClient::readsensor()
{
EnterCriticalSection(&_sensorCS);
{
while (_numsensorSampled >= _capacity) //no more sensors than the capacity size
{
UtilsLog("Queue full, not doing more sensor readings", UtilsDebug);
SleepConditionVariableCS(&_sensorQueueFullCV, &_sensorCS, INFINITE);
}
UtilsLog("Read sensor", UtilsDebug);
void* sensorreading = _fnSamplesensor();
_numsensorSampled++;
_localsensorQueue.push(sensorreading);
_sensorHandler->Sendreading(sensorreading);
}
WakeConditionVariable(&_sensorQueueEmptyCV);
LeaveCriticalSection(&_sensorCS);
}
void* AnalysisClient::Handlesensor()
{
//Spawn async thread if not already started
if (!_asyncsensorHandlerStarted)
{
_asyncsensorHandlerStarted = true;
CreateUtilsThread(Asyncreadsensor, this);
}
//Free memory from previous invocations
...
void* returnVal = NULL;
EnterCriticalSection(&_sensorCS);
{
while (_localsensorQueue.empty())
SleepConditionVariableCS(&_sensorQueueEmptyCV, &_sensorCS, INFINITE);
_lastreading = _localsensorQueue.front();
_localsensorQueue.pop();
returnVal = _lastreading;
_numsensorProcessed++;
}
LeaveCriticalSection(&_sensorCS);
return returnVal;
}
DWORD WINAPI AnalysisClient::Asyncreadsensor(void* Param)
{
//Create sensor Timer
_sensorTimer = CreateWaitableTimer(NULL, FALSE, NULL);
if (!_sensorTimer)
{
UtilsLog("Unable to create sensor waitable timer", UtilsError);
return 1;
}
AnalysisClient* This = (AnalysisClient*)Param;
This->WaitForsensor();
return 0;
}
bool CreateKahawaiThread(LPTHREAD_START_ROUTINE function, void* instance)
{
DWORD ThreadID;
HANDLE thread = CreateThread(NULL,0,function, instance, 0, &ThreadID);
if(thread==NULL)
return false;
return true;
}
执行日志显示了以下执行(右边的数值是消息写入日志时的时间(以毫秒为单位)。zi调整了对GetNewInterval的调用,使其始终返回1600000i64,这样我就可以将其作为问题源丢弃。不过,计时器调用之间的时间与此无关。可以看到的容量设置为5。
30621, Read sensor
30623, Read sensor
30624, Read sensor
30625, Read sensor
30626, Read sensor
30627, Queue full, not doing more sensor readings
30980, Read sensor
30981, Queue full, not doing more sensor readings
30997, Read sensor
30998, Queue full, not doing more sensor readings
31007, Read sensor
31008, Queue full, not doing more sensor readings
31019, Read sensor
31020, Queue full, not doing more sensor readings
31032, Read sensor
31033, Queue full, not doing more sensor readings
31040, Read sensor
31041, Queue full, not doing more sensor readings
31054, Read sensor
31055, Queue full, not doing more sensor readings
31066, Read sensor
31068, Queue full, not doing more sensor readings
31080, Read sensor
31081, Queue full, not doing more sensor readings
31087, Read sensor
31088, Queue full, not doing more sensor readings
31094, Read sensor
31096, Queue full, not doing more sensor readings
31111, Read sensor
31112, Queue full, not doing more sensor readings
31121, Read sensor
31123, Queue full, not doing more sensor readings
31180, Read sensor
31181, Queue full, not doing more sensor readings
31194, Read sensor
31197, Queue full, not doing more sensor readings
31294, Read sensor
31295, Queue full, not doing more sensor readings
31307, Read sensor
31308, Queue full, not doing more sensor readings
31316, Read sensor
31318, Queue full, not doing more sensor readings
31332, Read sensor
31333, Queue full, not doing more sensor readings
31336, Read sensor
31337, Queue full, not doing more sensor readings
31343, Read sensor
31344, Queue full, not doing more sensor readings
31359, Read sensor
31360, Queue full, not doing more sensor readings
31369, Read sensor
31371, Queue full, not doing more sensor readings
31384, Read sensor
31385, Queue full, not doing more sensor readings
31391, Read sensor
31392, Queue full, not doing more sensor readings
31398, Read sensor
31399, Queue full, not doing more sensor readings
错误是什么?有没有更好的方法来实现这一点?
感谢
您有
while (_numsensorSampled >= _capacity) //no more sensors than the capacity size
和
_localsensorQueue.push(sensorreading);
_numsensorSampled++;
和
_localsensorQueue.pop();
returnVal = _lastreading;
_numsensorProcessed++;
但没有
--_numsensorSampled;
所以
while (_numsensorSampled >= _capacity) //no more sensors than the capacity size
当你达到这个数字时,就会一直是真的。将其更改为
while (_numsensorSampled - numsensorProcessed >= _capacity) //no more sensors than the capacity size
也应该让它发挥作用。还有
WakeConditionVariable(&_sensorQueueEmptyCV);
LeaveCriticalSection(&_sensorCS);
看起来不对,也许应该是
LeaveCriticalSection(&_sensorCS);
WakeConditionVariable(&_sensorQueueEmptyCV);
否则,由于关键部分仍然处于活动状态,被唤醒的进程可能会立即再次进入睡眠状态。
相关文章:
- Pisano 周期生成器在 3 位周期内行为不正确
- 如何在共享库的整个生命周期内存储数据
- 提升图形库:资源受限的最短周期
- 我必须找到给定数组中所有数字的周期,就像有很多解决方案,但数组的大小是 10^5
- 如何理解句子的生命周期始于对e的评估
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了
- 找到包括特定边的最短周期
- Go/C++gRPC客户端通道和存根生命周期
- 如何将"this"的生命周期移动到C++中的另一个对象中?
- 是否可以通过使用移动/交换 c++11 来延长返回的临时变量的生命周期
- 如何在没有同步的情况下使用多个线程(2、4,8、16 个线程)在循环(10,100、1000 个周期)中打印字符串?
- C/C++ 经过的流程周期,不包括断点处
- 标准::计时::时钟、硬件时钟和周期计数
- 使用对象的生命周期作为设置器的安全性
- time_t的时钟周期和获取时间问题
- 查询时间/周期是针对所有内核/线程的序列化请求还是并行请求?
- 临时人员的生命周期传递给函数
- 使用贝尔曼福特检测产品超过阈值的周期
- 为什么这个循环每次迭代需要 1.32 个周期
- 具有可变周期的WaitableTimer