对于学校项目,目标是制造出3个过程中存在的实时系统,可以说"流程计算"one_answers"过程执行"。除了这两个过程之外,还有一个州持有人,我们将其称为"过程statecommunication",是两个过程的"过程"。每当司法通信的状态更改时,两个进程都应读取统计通信的状态,如果是该过程中使用的状态,则必须在该过程中执行诉讼。检索司法部门状态的最佳方法是什么?由于该状态控制了其他两个过程中发生的情况。最后一件事是,所有权利通信所做的就是相应地将状态调整为其他两个过程,因此它不会计算任何内容,这一切都发生在其他两个过程中。
对于计算和执行之间的通信,我们决定使用FIFO将数据从计算发送给执行者。但是,这似乎并不是统计通信的最佳解决方案,因为这应该是可以通过多个过程读取的FIFO。但是在FIFO中,一旦通过一个过程读取数据,所有数据就会从管道中消失。
现在我的问题是,从"统计通信"中检索状态的最佳方法是什么,可以通过多个过程不断检索?
以下是在C中实现状态机的一种方法。我使用了这种模式,因为我有一个设备可以实现带有某些外部源输入的状态计算机的设备。
这可以做很多方法,但是这种方法背后的核心思想是让工作线程(或进程)观看状态变量,具有主线程(或过程)观察状态过渡变量并相应地更改状态变量,然后根据接收到的外部数据更改状态过渡变量的独立线程(或过程)。
请记住,主线程必须"重置"状态过渡变量,以免它立即从新状态过渡。我是通过创建一个不运行过渡状态来做到的。由于主要和外部库都会写入状态过渡变量,因此我使用了一个互斥X进行保护。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <string.h>
pthread_mutex_t mutex;
typedef enum _State{
EXECUTE,
IDLE,
CALCULATE
} State;
typedef enum _StateTransition{
TRANS_EXECUTE,
TRANS_IDLE,
TRANS_CALCULATE,
TRANS_NOOP
} StateTransition;
void Calculate(State *state_p){
int flag = 0; // Only calculate once per state transition
while (1){
if ((*state_p == CALCULATE) && flag){
puts("Calculated");
flag = 0;
} else if (*state_p != CALCULATE){
flag = 1;
}
}
}
void Execute(State *state_p){
int flag = 0; // Only execute once per state transition
while (1){
if ((*state_p == EXECUTE) && flag){
puts("executed");
flag = 0;
} else if (*state_p != EXECUTE){
flag = 1;
}
}
}
void * ExternalSource(void * param){
StateTransition * transition_p = (StateTransition*) param;
// Emulate External input
while(1){
sleep(2);
puts("Transiton to idle");
pthread_mutex_lock(&mutex);
*transition_p = TRANS_IDLE;
pthread_mutex_unlock(&mutex);
sleep(2);
puts("Transition to calculate");
pthread_mutex_lock(&mutex);
*transition_p = TRANS_CALCULATE;
pthread_mutex_unlock(&mutex);
sleep(2);
puts("Transition to execute");
pthread_mutex_lock(&mutex);
*transition_p = TRANS_EXECUTE;
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t externalThread;
int rv;
pid_t pidExecute;
pid_t pidCalculate;
volatile StateTransition transition;
State * state;
// Setup Initial Values
transition = TRANS_NOOP;
state = mmap(NULL, sizeof(State), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
*state = IDLE;
// Create Processes for Calculate and Execute
pidExecute = fork();
if (pidExecute == 0){
Execute(state);
} else{
pidCalculate = fork();
if (pidCalculate == 0){
Calculate(state);
}
}
// Create Thread for Input Emulation
rv = pthread_create(&externalThread, NULL, ExternalSource, (void*)&transition);
if (rv){
perror("ERROR Unable to create thread");
return -1;
}
while(1){ //Implement State Machine
switch (*state){
case IDLE:
if (transition == TRANS_CALCULATE){
// Do some transition stuff
*state = CALCULATE; // Update new state
pthread_mutex_lock(&mutex);
transition = TRANS_NOOP; // Reset transition
pthread_mutex_unlock(&mutex);
}
break;
case CALCULATE:
if (transition == TRANS_EXECUTE){
// Do some transition stuff
*state = EXECUTE; // Update new state
pthread_mutex_lock(&mutex);
transition = TRANS_NOOP; // Reset transition
pthread_mutex_unlock(&mutex);
}
break;
case EXECUTE:
if (transition == TRANS_IDLE){
// Do some transition stuff
*state = IDLE; // Update new state
pthread_mutex_lock(&mutex);
transition = TRANS_NOOP; // Reset transition
pthread_mutex_unlock(&mutex);
}
break;
default:
break;
}
}
return 0;
}
此代码确实编译了,但它不是不是平台独立的。这实际上只是为了证明这个想法。如果您要使用此代码作为起点,请确保了解每行发生了什么,否则最终将花费您更多的时间。