多任务请求有限状态有限机c语言实现

确定的有限状态自动机

有限自动机作为一种识别装置,能准确的识别正规集。一个确定的有限状态自动机M是一个五元组:

M = { K , Σ , f , S , Z }

  • K是一个有穷集,它的每一个元素成为一个状态。
  • Σ 是一个有穷字母表,它的每个元素称为一个输入符号,所以也可以称 Σ 为输入符号表。
  • f是转换函数,是 K × Σ K 上的映像。
  • S ϵ K ,是唯一的一个终态。
  • Z K ,是一个终态集,终态也称为可接受状态或结束状态。

预备知识

要看懂有限机代码需要几个前提:typedef函数指针、互斥锁、循环队列。

1.typedef 函数指针

//typedef 返回类型(*新类型)(参数表)
//从内存上看,函数指针存储的就是函数的地址
#include<stdio.h>
typedef void (*Funcall)(char*,int);

void information(char* name,int years)
{
    printf("my name is %s and
            I'm %d years old;\n",name,years);
}

void fruit(char* name,int price)
{
    printf("%s price is %d\n",name,price);
}

int main()
{
    Funcall pFuncall;
    pFuncall = information;
    (*pFuncall)("wanghua",18);
    pFuncall = fruit;
    (*pFuncall)("apple",5);
    return 0;
}

2.循环队列

循环队列有两种实现形式,一种为数组,另一种为链表,有限自动机的输入一般进行宏定义,因此使用数组方式构成循环链表比较合适。数组从物理空间角度就是一块连续的地址,要从逻辑上实现循环队列需要进行处理,我们采用空出一个空间的方式,下面公式展示循环链表空、满、插入、删除操作的条件和计算:

#define MAX 100
typedef struct{
    int input[MAX];
    int head;
    int tail;
}Queue,*pQueue;
- 判断循环队列为空:head == tail
- 判断循环队列满:(tail + 1) % MAX == head
- 插入循环队列元素: tail = (tail + 1 ) % MAX
- 删除循环队列元素:head = ( head + 1 ) % MAX

3.互斥锁
学习过操作系统的童鞋应该对线程同步与互斥很熟悉,我们的循环列表是一个互斥资源,同一时间只允许一个写操作或读操作,因此对循环列表的所有操作必须在加锁和解锁之间进行。

     1、首先定义互斥锁变量,并初始化
         pthread_mutex_t mutex_lock;
         pthread_mutex_init(&mutex_lock,NULL);
     2、在操作前对互斥量进行加锁操作
         pthread_mutex_lock(&mutex_lock);
     3、操作完毕后进行解锁操作
        pthread_mutex_unlock(&mutex_lock);

代码讲解

  1. 有限自动机状态分析:
    如图1-1所示,{S1、S2、S3、S_trap}为状态,{c1、c2、c3}为输入,{a1、a2、a3}为动作,箭头指向表示在S1的状态下,输入c1,执行动作a1,转换到状态S2。
    这里写图片描述

当依次输入c1、c2、c3、c2时,状态机依次做出上表反应,当状态机遇到某个不能识别的输入时,就会进入陷阱状态,进入陷阱状态后无论输入什么都不会跳出。

状态 输入 动作 新状态
S1 c1 a1 S2
S2 c2 a2 S3
S3 c3 a3 S1
S1 c2 S_trap S_trap

2. 宏定义

//定义状态State
typedef int State;
#define States 4
#define State_1 0
#define State_2 1
#define State_3 2
#define State_trap 3

//定义输入Conditions
typedef int Conditions;
#define Conditions 3
#define Condition_1 0
#define Condition_2 1
#define Condition_3 2

//定义循环队列状态
typedef int bool;
#define OK 0
#define NODATA 1
#define OVERFLOW 2

3.结构体分析

从状态转换过程来看,我们需要一个状态机存储当前状态,一个跳转结构实现跳转过程,一个循环队列用于存储输入。

//状态机
typedef struct{
    State current;
    bool inTransition;  //判断状态机是否在转换状态
    Queue queue;         //存储输入
}StateMachine,*pStateMachine;

//跳转结构,此结构需要函数指针的配合
typedef void (*Action)(State state,Condition condition);
typedef struct{
    State next;
    Action action;  //动作函数指针,用来触发动作
}Transition,*pTransition;

//循环队列
typedef int bool
#define MAX 100;
typedef struct{
    int queue[MAX];
    int head;
    int tail;
    bool overflow;
}Queue,*pQueue;

4 .跳转功能实现

/*******************************************/
//跳转关系
//[s1,c1,a1,s2]
Transition t1 = { State_2, action_1};
//[s2,c2,a2,s3]
Transition t2 ={ State_3,action_2};
//[s3,c3,a3,s1]
Transition t3 = {State_1,action_3};
//[s1,c2,s_trap,s_trap]
Transition trap ={State_trap,action_trap};
/************************************************/
//定义动作
void action_1(State state,Condition condition)
{
    printf("Action_1 is running\n");
}
void action_2(State state,Condition condition)
{
    printf("Action_2 is running\n");
}
void action_3(State state,Condition condition)
{
    printf("Action_3 is running\n");
}
void action_trap(State state,Condition condition)
{
    printf("Action_trap is running\n");
}
/************************************************/
//定义跳转表,看不懂的可以看下面跳转表格
pTransition transition_table[States][Conditions]={
    &t1,&trap,&trap,
    &trap,&trap,&t2,
    &trap,&trap,&t3,
    &trap,&trap,&trap,
};
跳转表 c1 c2 c3
s1 action_1 action_trap action_trap
s2 action_trap action_2 action_trap
s3 action_trap action_trap action_3
trap action_trap action_trap action_trap

5.循环队列功能实现:

//入列
int push(pQueue queue,Condition c)
{
    pthread_mutex_lock(&mutex_lock); //上锁
    if(queue->head == queue->tail+1) //队列满
    {
        queue->overflow = true;
        local_irq_restore(flags);  //开终端
        return OVERFLOW;
    }
    else
    {
        queue->queue[queue->tail] = c;
        queue->tail = (queue->tail + 1) % MAX;
    }
    pthread_mutex_unlock(&mutex_lock); //解锁
    return OK;
}
//出列
int poll(pQueue queue,Condition *c)
{
    pthread_mutex_lock(&mutex_lock); //上锁
    if(queue->head == queue->tail)  //队列空
    {
        local_irq_restore(flags);  //开中断
        return NODATA;
    }
    else
    {
        *c = queue->queue[queue->head];
        queue->overflow = false;
        queue->head = (queue->head+1) % MAX;
    }
    pthread_mutex_unlock(&mutex_lock); //解锁
    return OK;
}

6.状态机功能实现


//状态机初始化
void initialize(pStateMachine machine,State s)
{
    machine->current = s;
    machine->inTransition = false;
    machine->queue.head =0 ;
    machine->queue.overflow = false;
}
//动作执行
static State takeAction(pStateMachine machine,Condition condition)
{
    State current = machine->current;
    pTransition p = transition_table[current][condition];
    (*(p->action))(current,condition);
    current = t->next;
    machine->current = current;
    return current;
}
//实现多输入处理
State multask(pStateMachine machine,Condition condition)
{
    int status;
    Condition next_condition;
    if(machine->inTransition)
    {
        push(&(machine->queue),condition);
        return  ;
    }
    else
    {
        machine->inTransition  = true;
        current = takeAction(machine,condition);
        status = poll(&(machine->queue),&next_condition);
        while(status == OK)
        {
            takeAction(machine,next_condition);
            status = poll(&(machine->queue),&next_condition);
        }
        machine->inTransition = false;
        return current;
    }
}

测试函数

 int main()
{ 
    Statemachine machine;
    initialStatemachine(&machine,State_1);
    multiplyTask(&machine,Condition_1);
    multiplyTask(&machine,Condition_2);
    return 0;
 }

这里写图片描述

完整代码

#include<stdio.h>
#include<pthread.h>
typedef int State;  //状态
typedef int Condition; //输入
typedef void (*Action)(State state,Condition condition); //函数指针

//宏定义
#define States 4
#define State_1 0
#define State_2 1
#define State_3 2 
#define State_trap 3

#define Conditions 3
#define Condition_1 0
#define Condition_2 1
#define COndition_3 2

#define OK 0
#define NODATA 1
#define OVERFLOW 2
#define MAX 100
//跳转结构体
typedef struct{
    State next;
    Action action;
}Transition,*pTransition;

//循环队列结构体
typedef struct{
    int queue[MAX];
    int head;
    int tail;
    int overflow;
}Queue,*pQueue;

//状态机结构体
typedef struct{
    State current;
    int inTransition;
    Queue squeue;
}Statemachine,*pStatemachine;

//动作函数声明
void action_1(State state,Condition condition);
void action_2(State state,Condition condition);
void action_3(State state,Condition condition);
void action_trap(State state,Condition condition);

//定义互斥锁变量
pthread_mutex_t mutex_lock;
//[s1,c1,a1,s2]
Transition t1 = {State_2,action_1};
//[s2,c2,a2,s3]
Transition t2 = {State_3,action_2};
//[s3,c3,a3,s1]
Transition t3 = {State_1,action_3};
//[s1,c2,trap,trap]
Transition trap = {State_trap,action_trap};

//动作函数
void action_1(State state,Condition condition)
{
    printf("action_1 is running\n");
    printf("State is %d and Condition is %d \n",state,condition);
}

void action_2(State state,Condition condition)
{
    printf("action_2 is running\n");
    printf("State is %d and Condition is %d\n ",state,condition);
}

void action_3(State state,Condition condition)
{
    printf("action_3 is running\n");
    printf("State is %d and Condition is %d \n",state,condition);
}

void action_trap(State state,Condition condition)
{
    printf("action_trap is running\n");
    printf("State is %d and Condition is %d\n ",state,condition);
}

//转换表
pTransition transition_table[States][Conditions]=
{
    &t1,&trap,&trap,
    &trap,&t2,&trap,
    &trap,&trap,&t3,
    &trap,&trap,&trap,
};

//插入循环表
int push(pQueue squeue,Condition condition)
{
    pthread_mutex_lock(&mutex_lock);
    if(squeue->head == (squeue->tail+ 1)) //队列满
    {
        squeue->overflow = true;
        return OVERFLOW ;
    }
    else                               
    {
        squeue->overflow = false;
        squeue->queue[squeue->tail]= condition;
        squeue->tail = (squeue->tail + 1 ) % MAX;

    }

    pthread_mutex_unlock(&mutex_lock);
    return OK;
}

//出队列

int poll(pQueue squeue,Condition *c)
{   
    pthread_mutex_init(&mutex_lock,NULL);
    pthread_mutex_lock(&mutex_lock);
    if(squeue->head == squeue->tail)  //空队列
    {
        squeue->overflow = false;
        return NODATA;
    }
    else
    {
        squeue->overflow = false ;
        *c= squeue->queue[squeue->head];
        squeue->head = (squeue->head + 1) % MAX ;
    }   
    pthread_mutex_unlock(&mutex_lock);
    return OK;
}

//状态机初始化

void initialStatemachine(pStatemachine machine,State state)
{
    machine->current = state;
    machine->inTransition = false;
    machine->squeue.head = 0 ;
    machine->squeue.tail = 0;
    machine->squeue.overflow = false;
}


//动作执行

static State takeAction(pStatemachine machine,Condition condition)
{
    State current = machine->current;
    pTransition t = transition_table[machine->current][condition];
    (*(t->action))(machine->current,condition);
    current = t->next;
    machine->current = current;
    return current;
}

//多输入执行

int multiplyTask(pStatemachine machine,Condition condition)
{
    int status;
    int next_condition;
    State current;
    if(machine->inTransition)
    {
        push(&(machine->squeue),condition);
        return OK;
    }
    else
    {
        machine->inTransition = true;
        current = takeAction(machine,condition);
        status = poll(&(machine->squeue),&next_condition);
        while(status == OK)
        {
            current = takeAction(machine,next_condition);
            status = poll(&(machine->squeue),&next_condition);
        }
        machine->inTransition = false;
    }   
    return current;
}

int main()
{

    Statemachine machine;
    initialStatemachine(&machine,State_1);
    multiplyTask(&machine,Condition_1);
    multiplyTask(&machine,Condition_2); 
    return 0;
}













猜你喜欢

转载自blog.csdn.net/Leader_wang/article/details/82624587