事件队列和互斥体
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 的内部而烦恼..
我正在 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 的内部而烦恼..