2016-01-11 137 views
1

我正在用几个有限状态机在qt/Linux中构建一个嵌入式系统。每个FSM都有自己的事件队列和一个连续运行的线程函数。 FSM可能会向彼此发布事件。EventQueues和互斥体

显然事件队列在访问时应该被锁定和解锁。 我应该将互斥锁放入FSM,EventQueue还是将全局变量传递给FSM?

下面是伪代码:

class EventQueue { 

     int queue[100]; 
     int head; 
     int tail; 

     void postEvent(int event) { 
      // place the event to circular buffer 
      // checking of head/tail neglected 
      queue[tail++] = event; 
     } 

     int getNextEvent() { 
      // checking of head/tail neglected 
      return queue[head++]; 
     } 

     bool isEmpty() { 
      return false; // or true if the queue is not empty 
     } 
    }; 

    class FSM { 
     EventQueue queue; 
     FSM * other; 
     pthread_t thread; 

     void start() { 
      int t = pthread_create(&thread, NULL, FSM::run, NULL); 

     } 

     // thread function 
     void * run(void *) { 

      while (true) { 

       if (!queue.isEmpty()) { 
        int e = queue.getNextEvent(); 
        dispatch(e);  // should be perform by state class actually 
       } 
      } 
     } 

     virtual void dispatch(int event) = 0; 
    }; 

    class FSM_A : FSM { 

     void dispatch(int event) { 

      other->postEvent(1234); // send event to other state machine 
      usleep(100); 
     } 
    }; 

    class FSM_B : FSM { 

     void dispatch(int event) { 

      other->postEvent(4567); // send event to other state machine 
      usleep(200); 
     } 
    }; 

    void main() { 
     FSM_A fsmA; 
     FSM_B fsmB; 

     fsmA.other = &fsmB; 
     fsmB.other = &fsmA; 

     fsmA.start(): 
     fsmB.start(): 
    } 

谢谢!

回答

2

我认为最简单的解决方案是互斥你的队列。

class EventQueue { 

    int queue[100]; 
    int head; 
    int tail; 
    Mutex mutex; // std::mutex or QMutex or whatever you prefer. 

    void postEvent(int event) { 
     MutexLocker(mutex); // f.e. QMutextLocker or std::lock_guard 
     // place the event to circular buffer 
     // checking of head/tail neglected 
     queue[tail++] = event; 
    } 

    int getNextEvent() { 
     MutexLocker(mutex); 
     // checking of head/tail neglected 
     return queue[head++]; 
    } 

    bool isEmpty() { 
     // No lock is needed if no variables are read. 
     return false; // or true if the queue is not empty 
    } 
}; 

如果一个变量读/从一个以上的线程写的,它是非常重要的,而读/写过程中每一个读或写指令被锁定。

当访问其中一个命令队列时,不需要锁定每个命令队列。我会将这个互斥锁放入EventQueue

edit:正如在注释中指出的那样,使用MutexLocker锁定互斥锁更安全。这样你就可以确定当函数作用域结束时它会被释放。

+0

'bool isEmpty(){mutex.lock();返回false; mutex.unlock(); }和你的互斥锁永远不会解锁!返回后无法访问。 – Evgeny

+0

您应该改用QMutexLocker。 – Evgeny

+0

好赶上哈哈。确实使用mutexlocker来避免这些booboos – Teimpz

1

按照methodology..If类FSM使用EventQueue中,并EventQueue的内部管理它的事件队列SOLID设计单一职责原则,那么,它的EventQueue负责处理它自己的内部队列usage.The FSM不需要关心EventQueue内部的问题。

+0

据此,互斥量应该在事件队列中,所以FSMs不必为此烦恼...... –

+0

因此而改变:) – basav