EventQueues and Mutex

EventQueues and Mutex

本文关键字:Mutex and EventQueues      更新时间:2023-10-16

我正在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():
    }

谢谢!

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

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来锁定互斥锁要安全得多。通过这种方式,您可以确保它将在函数范围结束时释放。

遵循SOLID设计方法中的单一责任原则。。如果类FSM使用eventQueue,并且eventQueue在内部管理它的事件队列,那么eventQueue负责处理它自己的内部队列使用情况。FSM不必为EventQueue的内部问题而烦恼。。