C++ C++;带定时器的线程状态机

C++ C++;带定时器的线程状态机,c++,multithreading,timer,C++,Multithreading,Timer,说明部分: 我试着读了几篇有线索的文章,但我对这个话题还很陌生,所以我不确定我是否能完成我所想的。 基于本教程,我已经实现了一个面向对象的状态机来检测运动 还有一个关于状态机多线程的教程,但是这个例子对我来说有点复杂,并且是为windows实现的,所以现在我尝试自己去做。目标是使多个最终状态机并行运行,以标记传感器信息。我认为需要多线程,因为事件将异步到达,并且应确保处理每个信息(还必须实现队列) 如图所示,我的FSM有4种状态,应该在一个线程内实现。它将等待事件(移动或计时器)发生并转换到下一

说明部分:

我试着读了几篇有线索的文章,但我对这个话题还很陌生,所以我不确定我是否能完成我所想的。 基于本教程,我已经实现了一个面向对象的状态机来检测运动 还有一个关于状态机多线程的教程,但是这个例子对我来说有点复杂,并且是为windows实现的,所以现在我尝试自己去做。目标是使多个最终状态机并行运行,以标记传感器信息。我认为需要多线程,因为事件将异步到达,并且应确保处理每个信息(还必须实现队列)

如图所示,我的FSM有4种状态,应该在一个线程内实现。它将等待事件(移动或计时器)发生并转换到下一个状态。状态保存在对象中,转换基于对象函数

问题部分:

移动事件将从外部触发(接收传感器事件)。 根据事件的不同,我可以执行相应的对象函数,将其更改为下一个状态


但是我怎么知道定时器是在触发某个状态后运行的,而该状态最终会导致前一个状态。如果另一个事件发生异步,计时器也必须停止。这应该在线程内部处理还是在线程外部处理

我看不出有什么动机在这种情况下使用多线程。因此,“线程安全”不是一个问题。您将定义一些表示“状态机”及其内部状态的软件对象,以及两个可以调用的方法,每个可能的通知一个。这些应该按顺序处理:一条消息到达(在线程安全队列中)告诉您计时器已关闭,或者一条消息到达告诉您有关警报的情况,然后您一次弹出并处理一条消息。或者,您可以在方法中使用互斥锁,以确保从不同时尝试两个方法调用。。。如果这是个问题,我看不出有什么理由。只要在一个线程中完成所有这些,就可以完成

显然,您的状态机会收到两个通知:(1)计时器刚刚关闭,以及(2)传感器/警报有什么要报告

然后,你只需根据(1)当前状态和(2)各种内部变量,计算出每种情况下需要发生的逻辑。状态机中的逻辑处理这两种情况:实际上没有并行的操作

case state == MOVING_BETWEEN_ROOM:
   case stimulus == TIMER_POP:
     timer_counter++;
     if timer_counter > 1 then {
       state = UNSURE_MOVEMENT;
       timer_counter = 0;             // maybe?
     }
   case stimulus == ALARM:
     timer_counter = 0;
     if current_room == room_last_alarm {
        same_room_count++;
        if in_same_room_count > n then {
          state = MOVING_SAME_ROOM;
          in_same_room_count = 0;    // maybe???
        }
     } else {
        in_same_room_count = 0;
        room_last_alarm = current_room;
     }

。。。等等我不是说上面的逻辑是正确的,但它应该为您指明正确的方向。

您打算在任何GUI框架中运行代码吗?它们通常提供一些“计时器”功能,允许您在指定的未来时间从框架的事件线程*请求回调。(*a.k.a.,“事件调度线程”,“应用程序线程”,“主线程,”…)不,这个软件将在raspberry上运行,由like控制器提供各种其他功能。好的,但FWIW,“raspberry”并不意味着“没有GUI”。Pi完全可以托管GUI应用程序。@SolomonSlow是的,我知道:)。但该软件并不打算与gui一起运行。已经有一个现有的框架,我将在其中集成此软件,以感谢您的回答。我想到了多线程,因为我需要同时做不同的事情,而事件也会在线程仍在执行时异步到达。一个线程用于数据处理(队列等),其他线程用于状态机。以及用于根据状态机和数据输入保存信息的最后一个线程