代码之家  ›  专栏  ›  技术社区  ›  Alvin

事件队列和Mutex

  •  1
  • Alvin  · 技术社区  · 9 年前

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

    显然,访问时应该锁定和解锁事件队列。 我应该将互斥体放在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 回复  |  直到 9 年前
        1
  •  2
  •   Teimpz    9 年前

    我认为最简单的解决方案是将队列锁定为静音。

    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中

    编辑:正如评论中所指出的,使用MutexLocker锁定互斥锁要安全得多。这样,您可以确保在函数作用域结束时它将被释放。

        2
  •  1
  •   basav    9 年前

    遵循 单一责任原则 在里面 固体 如果类FSM使用eventQueue,并且eventQueue在内部管理它的事件队列,那么eventQueue's负责处理它自己的内部队列使用。FSM不必担心EventQueue的内部问题。。