事件队列和互斥体

EventQueues and Mutex

我正在 qt/Linux 中使用多个有限状态机构建一个嵌入式系统。每个 FSM 都有自己的事件队列和线程函数 运行 连续。 FSM 可能 post 事件给彼此。

显然事件队列应该在访问时被锁定和解锁。 我应该将互斥量放在 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
    }
};

如果一个变量 read/written 来自多个线程,那么在 read/write 进行时锁定每个读取或写入指令很重要。

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

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

SOLID设计方法中遵循单一职责原则。如果class FSM使用eventQueue,和EventQueue在内部管理它的事件队列,然后,EventQueue 有责任处理它自己的内部队列 usage.The FSM 不需要为 EventQueue 的内部而烦恼..