我尝试在具有有限库函数的嵌入式设备上实现C ++中的周期性事件。我不能使用睡眠或其他延迟,因为它会停止当前的执行。
例如。
do
{
if(something)
{
//Do something
}
if(something)
{
//Do something
}
if(every 5 minutes)
{
//Do something only once after 5 minutes
}
}
while(true)
我不知道该如何解决这个问题。你可以帮我解决这个问题,因为我需要在这个while循环中实现这个吗?我会使用线程,但在这个设备上并不可能,所以我正在寻找另一种方式。
答案 0 :(得分:3)
当然,建议产生一个单独的线程(我会做的)或使用评论中给出的alarm()
是很好的建议,但可能无法在您的设备上使用。但是,专注于您当前的方法,通常的想法是,伪代码:
last action time = current time
while (true) {
do things.
if current time - last action time >= 5 minutes then
perform action
last action time = current time
// or last action time += 5 minutes if you want to mitigate drift
end
}
所以现在你只需要选择自己喜欢的方式来获取当前时间。在桌面平台上,您可以使用例如一些嵌入式平台也可以提供这些内容,time()
,gettimeofday()
,GetTickCount()
在Windows上等。但是,这可能会有问题:
由于您在评论中提到您正在使用嵌入式设备,"您最喜欢的方式来获取当前时间"将根据平台而有所不同,您只需检查设备文档即可。如果您很幸运,您的MCU可能会提供一种查询CPU计数器的方法,以及您通常从设置中知道的频率。但它可能没有。
如果没有,另一种选择是您的设备提供板载定时器。在这种情况下,您可以配置它并响应周期性中断,在这种情况下,您的两个选项通常是:
volatile
标志,检查主循环中的该标志并执行操作+如果设置了则重置该标志。这通常是一种更简单的方法。这样做在架构上与使用alarm()
类似。但是,确实存在实现time()
和/或gettimeofday()
的嵌入式平台。但那些是你的选择。
答案 1 :(得分:0)
这听起来像是在寻找两种不同的功能;一,在不中断执行的情况下发送命令;二,等待一定的时间。首先,您正在寻找异步编程。对于第二个,我建议Boost::io_service
。要结合这两者,请查看private void button6_Click(object sender, EventArgs e)
{
GetNumber gtn = new GetNumber();
gtn.Show();
System.Timers.Timer timer = new Timer(6000);
timer.Elapsed += (_, _2) => { Invoke((MethodInvoker)delegate { gtn.Close(); }); };
timer.Start();
}
,这将允许您在使用或不使用计时器的情况下注册异步回调。