The finite state machine
2013-10-23 23:01
441 查看
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "relayer.h"
#define TTY1 "/dev/tty11"
#define TTY2 "/dev/tty12"
#define TTY3 "/dev/tty10"
#define TTY4 "/dev/tty9"
int main()
{
int fd1,fd2,fd3,fd4;
int job1,job2;
struct rel_stat_st st;
fd1 = open(TTY1,O_RDWR);
if(fd1 < 0)
{
perror("open()");
exit(1);
}
write(fd1,"TTY1\n",5);
fd2 = open(TTY2,O_RDWR|O_NONBLOCK);
if(fd2 < 0)
{
perror("open()");
exit(1);
}
write(fd2,"TTY2\n",5);
job1 = rel_addjob(fd1,fd2);
if(job1 < 0)
{
fprintf(stderr,"rel_addjob():%s\n",strerror(-job1));
exit(1);
}
fd3 = open(TTY3,O_RDWR);
if(fd3 < 0)
{
perror("open()");
exit(1);
}
write(fd3,"TTY3\n",5);
fd4 = open(TTY4,O_RDWR|O_NONBLOCK);
if(fd4 < 0)
{
perror("open()");
exit(1);
}
write(fd4,"TTY4\n",5);
job2 = rel_addjob(fd3,fd4);
if(job2 < 0)
{
fprintf(stderr,"rel_addjob():%s\n",strerror(-job2));
exit(1);
}
// 忙等(判断假错)
while(1)
{
rel_statjob(job1,&st);
printf("job1:1->2(%lld)\t2->1(%lld)\n",st.count12,st.count21);
rel_statjob(job2,&st);
printf("job2:1->2(%lld)\t2->1(%lld)\n",st.count12,st.count21);
puts("");
sleep(1);
}
close(fd1);
close(fd2);
close(fd3);
close(fd4);
exit(0);
}
-----------------------------------------------------------------------------------------------
// 负载均衡器(serviver)
//查寻法
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include "relayer.h"
#define BUFSIZE 1024
enum
{
STATE_R=1,
STATE_W,
STATE_Ex,
STATE_T
};
// 状态机的状态
struct rel_fsa_st
{
int state;
int sfd,dfd;
int64_t count;//成功写入的字节数
char buf[BUFSIZE];
int len,pos;
char *errstr;
};
//
struct rel_job_st
{
int fd1,fd2;
int job_state;
pthread_mutex_t mut_job_state;
pthread_cond_t cond_job_state;
struct rel_fsa_st fsa12,fsa21;
int fd1_save,fd2_save;
// struct timeval start,end;
};
static struct rel_job_st *rel_job[REL_JOBMAX];
static pthread_mutex_t mut_rel_job = PTHREAD_MUTEX_INITIALIZER;
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
static void fetch_stat_unlocked(int id,struct rel_stat_st *statp);
static void fsa_driver(struct rel_fsa_st *fsa)
{
int ret;
switch(fsa->state)
{
case STATE_R:
fsa->len = read(fsa->sfd,fsa->buf,BUFSIZE);
if(fsa->len == 0)
fsa->state = STATE_T;
else if(fsa->len < 0)
{
if(errno == EAGAIN)
fsa->state = STATE_R;
else
{
fsa->state = STATE_Ex;
fsa->errstr = "read()";
}
}
else
{
fsa->pos = 0;
fsa->state = STATE_W;
}
break;
case STATE_W:
ret = write(fsa->dfd,fsa->buf+fsa->pos,fsa->len);
if(ret < 0)
{
if(errno == EAGAIN)
fsa->state = STATE_W;
else
{
fsa->errstr = "write()";
fsa->state = STATE_Ex;
}
}
else
{
fsa->pos += ret;
fsa->len -= ret;
fsa->count += ret;
if(fsa->len == 0)
fsa->state = STATE_R;
else
fsa->state = STATE_W;
}
break;
case STATE_Ex:
perror(fsa->errstr);
fsa->state = STATE_T;
break;
case STATE_T:/*do nothing*/
break;
default:
abort();
break;
}
}
static void *thr_relayer(void *unused)
{
int i;
while(1)
{
pthread_mutex_lock(&mut_rel_job);
for(i = 0 ;i < REL_JOBMAX; i++)
{
if(rel_job[i] != NULL)
{
pthread_mutex_lock(&rel_job[i]->mut_job_state);
if(rel_job[i]->job_state==STATE_RUNNING)
{
fsa_driver(&rel_job[i]->fsa12);
fsa_driver(&rel_job[i]->fsa21);
if(rel_job[i]->fsa12.state == STATE_T && \
rel_job[i]->fsa21.state == STATE_T)
{
rel_job[i]->job_state = STATE_OVER;
pthread_cond_broadcast(&rel_job[i]->cond_job_state);
}
}
pthread_mutex_unlock(&rel_job[i]->mut_job_state);
}
}
pthread_mutex_unlock(&mut_rel_job);
}
}
static void module_load(void)
{
int err;
pthread_t tid_relayer;
err = pthread_create(&tid_relayer,NULL,thr_relayer,NULL);
if(err)
{
fprintf(stderr,"pthread_create():%s\n",strerror(err));
exit(1);
}
}
static int get_free_pos_unlocked(void)
{
int i;
for(i = 0 ;i < REL_JOBMAX; i++)
if(rel_job[i] == NULL)
return i;
return -1;
}
int rel_addjob(int fd1,int fd2)
{
int pos;
struct rel_job_st *me;
pthread_once(&init_once,module_load);
if(fd1 < 0 || fd2 < 0)
return -EINVAL;
me = malloc(sizeof(*me));
if(me == NULL)
return -ENOMEM;
me->fd1 = fd1;
me->fd2 = fd2;
me->job_state = STATE_RUNNING;
pthread_mutex_init(&me->mut_job_state,NULL);
pthread_cond_init(&me->cond_job_state,NULL);
me->fd1_save = fcntl(me->fd1,F_GETFL);
fcntl(me->fd1,F_SETFL,me->fd1_save|O_NONBLOCK);
me->fd2_save = fcntl(me->fd2,F_GETFL);
fcntl(me->fd2,F_SETFL,me->fd2_save|O_NONBLOCK);
me->fsa12.sfd = me->fd1;
me->fsa12.dfd = me->fd2;
me->fsa12.state = STATE_R;
me->fsa12.count = 0;
me->fsa21.sfd = me->fd2;
me->fsa21.dfd = me->fd1;
me->fsa21.state = STATE_R;
me->fsa21.count = 0;
pthread_mutex_lock(&mut_rel_job);
pos = get_free_pos_unlocked();
if(pos < 0)
{
pthread_mutex_unlock(&mut_rel_job);
fcntl(me->fd1,F_SETFL,me->fd1_save);
fcntl(me->fd2,F_SETFL,me->fd2_save);
free(me);
return -ENOSPC;
}
rel_job[pos] = me;
pthread_mutex_unlock(&mut_rel_job);
return pos;
}
int rel_canceljob(int id)
{
pthread_mutex_lock(&mut_rel_job);
if(id < 0 || id >= REL_JOBMAX || rel_job[id] == NULL)
{
pthread_mutex_unlock(&mut_rel_job);
return -EINVAL;
}
pthread_mutex_lock(&rel_job[id]->mut_job_state);
if(rel_job[id]->job_state == STATE_CANCELED)
{
pthread_mutex_unlock(&rel_job[id]->mut_job_state);
pthread_mutex_unlock(&mut_rel_job);
return -ECANCELED;
}
if(rel_job[id]->job_state == STATE_OVER)
{
pthread_mutex_unlock(&rel_job[id]->mut_job_state);
pthread_mutex_unlock(&mut_rel_job);
return -EBUSY;
}
rel_job[id]->job_state = STATE_CANCELED ;
pthread_cond_broadcast(&rel_job[id]->cond_job_state);
pthread_mutex_unlock(&rel_job[id]->mut_job_state);
pthread_mutex_unlock(&mut_rel_job);
return 0;
}
int rel_waitjob(int id,struct rel_stat_st *statp)
{
pthread_mutex_lock(&mut_rel_job);
if(id < 0 || id >= REL_JOBMAX || rel_job[id] == NULL)
{
pthread_mutex_unlock(&mut_rel_job);
return -EINVAL;
}
pthread_mutex_lock(&rel_job[id]->mut_job_state);
while(rel_job[id]->job_state == STATE_RUNNING)
pthread_cond_wait(&rel_job[id]->cond_job_state,&rel_job[id]->mut_job_state);
if(statp != NULL)
fetch_stat_unlocked(id ,statp);
pthread_mutex_unlock(&rel_job[id]->mut_job_state);
pthread_mutex_destroy(&rel_job[id]->mut_job_state);
pthread_cond_destroy(&rel_job[id]->cond_job_state);
fcntl(rel_job[id]->fd1,F_SETFL,rel_job[id]->fd1_save);
fcntl(rel_job[id]->fd2,F_SETFL,rel_job[id]->fd2_save);
free(rel_job[id]);
rel_job[id] = NULL;
pthread_mutex_unlock(&mut_rel_job);
return 0;
}
static void fetch_stat_unlocked(int id,struct rel_stat_st *statp)
{
statp->fd1 = rel_job[id]->fd1;
statp->fd2 = rel_job[id]->fd2;
statp->state = rel_job[id]->job_state;
statp->count12 = rel_job[id]->fsa12.count;
statp->count21 = rel_job[id]->fsa21.count;
}
int rel_statjob(int id ,struct rel_stat_st *statp)
{
pthread_mutex_lock(&mut_rel_job);
if(id < 0 || id >= REL_JOBMAX || rel_job[id] == NULL)
{
pthread_mutex_unlock(&mut_rel_job);
return -EINVAL;
}
fetch_stat_unlocked(id,statp);
pthread_mutex_unlock(&mut_rel_job);
return 0;
}
--------------------------------------------------------------------------------------------
#ifndef RELAYER_H__
#define RELAYER_H__
#define REL_JOBMAX 10000
//任务状态
enum
{
STATE_RUNNING=1,
STATE_CANCELED, //被取消
STATE_OVER
};
//user's structure (提取结构体的一部分),半封装形式
struct rel_stat_st
{
int fd1,fd2;
int state;
int64_t count12,count21;
// struct timeval start,end;
};
int rel_addjob(int fd1,int fd2);
/*
* return : >= 0 成功,返回任务标识
* == -ENOMEM 失败,内存分配失败
* == -ENOSPC 失败,任务数组已满
* == -EINVAL 失败,参数非法
* */
int rel_canceljob(int );
/*
* return : == 0 成功,指定任务已取消
* == -EINVAL 失败,参数非法
* == -EBUSY 失败,任务已正常终止
* == -ECANCELED 失败,任务早已被取消
* */
int rel_waitjob(int,struct rel_stat_st *);
/*
* return : == 0 成功,指定任务已终止并返回状态
* == -EINVAL 失败,参数非法
* */
//指定任务瞬间状态
int rel_statjob(int,struct rel_stat_st *);
/*
* return : == 0 成功,指定任务状态已返回
* == -EINVAL 失败,参数非法
* */
#endif
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "relayer.h"
#define TTY1 "/dev/tty11"
#define TTY2 "/dev/tty12"
#define TTY3 "/dev/tty10"
#define TTY4 "/dev/tty9"
int main()
{
int fd1,fd2,fd3,fd4;
int job1,job2;
struct rel_stat_st st;
fd1 = open(TTY1,O_RDWR);
if(fd1 < 0)
{
perror("open()");
exit(1);
}
write(fd1,"TTY1\n",5);
fd2 = open(TTY2,O_RDWR|O_NONBLOCK);
if(fd2 < 0)
{
perror("open()");
exit(1);
}
write(fd2,"TTY2\n",5);
job1 = rel_addjob(fd1,fd2);
if(job1 < 0)
{
fprintf(stderr,"rel_addjob():%s\n",strerror(-job1));
exit(1);
}
fd3 = open(TTY3,O_RDWR);
if(fd3 < 0)
{
perror("open()");
exit(1);
}
write(fd3,"TTY3\n",5);
fd4 = open(TTY4,O_RDWR|O_NONBLOCK);
if(fd4 < 0)
{
perror("open()");
exit(1);
}
write(fd4,"TTY4\n",5);
job2 = rel_addjob(fd3,fd4);
if(job2 < 0)
{
fprintf(stderr,"rel_addjob():%s\n",strerror(-job2));
exit(1);
}
// 忙等(判断假错)
while(1)
{
rel_statjob(job1,&st);
printf("job1:1->2(%lld)\t2->1(%lld)\n",st.count12,st.count21);
rel_statjob(job2,&st);
printf("job2:1->2(%lld)\t2->1(%lld)\n",st.count12,st.count21);
puts("");
sleep(1);
}
close(fd1);
close(fd2);
close(fd3);
close(fd4);
exit(0);
}
-----------------------------------------------------------------------------------------------
// 负载均衡器(serviver)
//查寻法
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include "relayer.h"
#define BUFSIZE 1024
enum
{
STATE_R=1,
STATE_W,
STATE_Ex,
STATE_T
};
// 状态机的状态
struct rel_fsa_st
{
int state;
int sfd,dfd;
int64_t count;//成功写入的字节数
char buf[BUFSIZE];
int len,pos;
char *errstr;
};
//
struct rel_job_st
{
int fd1,fd2;
int job_state;
pthread_mutex_t mut_job_state;
pthread_cond_t cond_job_state;
struct rel_fsa_st fsa12,fsa21;
int fd1_save,fd2_save;
// struct timeval start,end;
};
static struct rel_job_st *rel_job[REL_JOBMAX];
static pthread_mutex_t mut_rel_job = PTHREAD_MUTEX_INITIALIZER;
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
static void fetch_stat_unlocked(int id,struct rel_stat_st *statp);
static void fsa_driver(struct rel_fsa_st *fsa)
{
int ret;
switch(fsa->state)
{
case STATE_R:
fsa->len = read(fsa->sfd,fsa->buf,BUFSIZE);
if(fsa->len == 0)
fsa->state = STATE_T;
else if(fsa->len < 0)
{
if(errno == EAGAIN)
fsa->state = STATE_R;
else
{
fsa->state = STATE_Ex;
fsa->errstr = "read()";
}
}
else
{
fsa->pos = 0;
fsa->state = STATE_W;
}
break;
case STATE_W:
ret = write(fsa->dfd,fsa->buf+fsa->pos,fsa->len);
if(ret < 0)
{
if(errno == EAGAIN)
fsa->state = STATE_W;
else
{
fsa->errstr = "write()";
fsa->state = STATE_Ex;
}
}
else
{
fsa->pos += ret;
fsa->len -= ret;
fsa->count += ret;
if(fsa->len == 0)
fsa->state = STATE_R;
else
fsa->state = STATE_W;
}
break;
case STATE_Ex:
perror(fsa->errstr);
fsa->state = STATE_T;
break;
case STATE_T:/*do nothing*/
break;
default:
abort();
break;
}
}
static void *thr_relayer(void *unused)
{
int i;
while(1)
{
pthread_mutex_lock(&mut_rel_job);
for(i = 0 ;i < REL_JOBMAX; i++)
{
if(rel_job[i] != NULL)
{
pthread_mutex_lock(&rel_job[i]->mut_job_state);
if(rel_job[i]->job_state==STATE_RUNNING)
{
fsa_driver(&rel_job[i]->fsa12);
fsa_driver(&rel_job[i]->fsa21);
if(rel_job[i]->fsa12.state == STATE_T && \
rel_job[i]->fsa21.state == STATE_T)
{
rel_job[i]->job_state = STATE_OVER;
pthread_cond_broadcast(&rel_job[i]->cond_job_state);
}
}
pthread_mutex_unlock(&rel_job[i]->mut_job_state);
}
}
pthread_mutex_unlock(&mut_rel_job);
}
}
static void module_load(void)
{
int err;
pthread_t tid_relayer;
err = pthread_create(&tid_relayer,NULL,thr_relayer,NULL);
if(err)
{
fprintf(stderr,"pthread_create():%s\n",strerror(err));
exit(1);
}
}
static int get_free_pos_unlocked(void)
{
int i;
for(i = 0 ;i < REL_JOBMAX; i++)
if(rel_job[i] == NULL)
return i;
return -1;
}
int rel_addjob(int fd1,int fd2)
{
int pos;
struct rel_job_st *me;
pthread_once(&init_once,module_load);
if(fd1 < 0 || fd2 < 0)
return -EINVAL;
me = malloc(sizeof(*me));
if(me == NULL)
return -ENOMEM;
me->fd1 = fd1;
me->fd2 = fd2;
me->job_state = STATE_RUNNING;
pthread_mutex_init(&me->mut_job_state,NULL);
pthread_cond_init(&me->cond_job_state,NULL);
me->fd1_save = fcntl(me->fd1,F_GETFL);
fcntl(me->fd1,F_SETFL,me->fd1_save|O_NONBLOCK);
me->fd2_save = fcntl(me->fd2,F_GETFL);
fcntl(me->fd2,F_SETFL,me->fd2_save|O_NONBLOCK);
me->fsa12.sfd = me->fd1;
me->fsa12.dfd = me->fd2;
me->fsa12.state = STATE_R;
me->fsa12.count = 0;
me->fsa21.sfd = me->fd2;
me->fsa21.dfd = me->fd1;
me->fsa21.state = STATE_R;
me->fsa21.count = 0;
pthread_mutex_lock(&mut_rel_job);
pos = get_free_pos_unlocked();
if(pos < 0)
{
pthread_mutex_unlock(&mut_rel_job);
fcntl(me->fd1,F_SETFL,me->fd1_save);
fcntl(me->fd2,F_SETFL,me->fd2_save);
free(me);
return -ENOSPC;
}
rel_job[pos] = me;
pthread_mutex_unlock(&mut_rel_job);
return pos;
}
int rel_canceljob(int id)
{
pthread_mutex_lock(&mut_rel_job);
if(id < 0 || id >= REL_JOBMAX || rel_job[id] == NULL)
{
pthread_mutex_unlock(&mut_rel_job);
return -EINVAL;
}
pthread_mutex_lock(&rel_job[id]->mut_job_state);
if(rel_job[id]->job_state == STATE_CANCELED)
{
pthread_mutex_unlock(&rel_job[id]->mut_job_state);
pthread_mutex_unlock(&mut_rel_job);
return -ECANCELED;
}
if(rel_job[id]->job_state == STATE_OVER)
{
pthread_mutex_unlock(&rel_job[id]->mut_job_state);
pthread_mutex_unlock(&mut_rel_job);
return -EBUSY;
}
rel_job[id]->job_state = STATE_CANCELED ;
pthread_cond_broadcast(&rel_job[id]->cond_job_state);
pthread_mutex_unlock(&rel_job[id]->mut_job_state);
pthread_mutex_unlock(&mut_rel_job);
return 0;
}
int rel_waitjob(int id,struct rel_stat_st *statp)
{
pthread_mutex_lock(&mut_rel_job);
if(id < 0 || id >= REL_JOBMAX || rel_job[id] == NULL)
{
pthread_mutex_unlock(&mut_rel_job);
return -EINVAL;
}
pthread_mutex_lock(&rel_job[id]->mut_job_state);
while(rel_job[id]->job_state == STATE_RUNNING)
pthread_cond_wait(&rel_job[id]->cond_job_state,&rel_job[id]->mut_job_state);
if(statp != NULL)
fetch_stat_unlocked(id ,statp);
pthread_mutex_unlock(&rel_job[id]->mut_job_state);
pthread_mutex_destroy(&rel_job[id]->mut_job_state);
pthread_cond_destroy(&rel_job[id]->cond_job_state);
fcntl(rel_job[id]->fd1,F_SETFL,rel_job[id]->fd1_save);
fcntl(rel_job[id]->fd2,F_SETFL,rel_job[id]->fd2_save);
free(rel_job[id]);
rel_job[id] = NULL;
pthread_mutex_unlock(&mut_rel_job);
return 0;
}
static void fetch_stat_unlocked(int id,struct rel_stat_st *statp)
{
statp->fd1 = rel_job[id]->fd1;
statp->fd2 = rel_job[id]->fd2;
statp->state = rel_job[id]->job_state;
statp->count12 = rel_job[id]->fsa12.count;
statp->count21 = rel_job[id]->fsa21.count;
}
int rel_statjob(int id ,struct rel_stat_st *statp)
{
pthread_mutex_lock(&mut_rel_job);
if(id < 0 || id >= REL_JOBMAX || rel_job[id] == NULL)
{
pthread_mutex_unlock(&mut_rel_job);
return -EINVAL;
}
fetch_stat_unlocked(id,statp);
pthread_mutex_unlock(&mut_rel_job);
return 0;
}
--------------------------------------------------------------------------------------------
#ifndef RELAYER_H__
#define RELAYER_H__
#define REL_JOBMAX 10000
//任务状态
enum
{
STATE_RUNNING=1,
STATE_CANCELED, //被取消
STATE_OVER
};
//user's structure (提取结构体的一部分),半封装形式
struct rel_stat_st
{
int fd1,fd2;
int state;
int64_t count12,count21;
// struct timeval start,end;
};
int rel_addjob(int fd1,int fd2);
/*
* return : >= 0 成功,返回任务标识
* == -ENOMEM 失败,内存分配失败
* == -ENOSPC 失败,任务数组已满
* == -EINVAL 失败,参数非法
* */
int rel_canceljob(int );
/*
* return : == 0 成功,指定任务已取消
* == -EINVAL 失败,参数非法
* == -EBUSY 失败,任务已正常终止
* == -ECANCELED 失败,任务早已被取消
* */
int rel_waitjob(int,struct rel_stat_st *);
/*
* return : == 0 成功,指定任务已终止并返回状态
* == -EINVAL 失败,参数非法
* */
//指定任务瞬间状态
int rel_statjob(int,struct rel_stat_st *);
/*
* return : == 0 成功,指定任务状态已返回
* == -EINVAL 失败,参数非法
* */
#endif
相关文章推荐
- paper:synthesizable finite state machine design techniques using the new systemverilog 3.0 enhancements 之 FSM Coding Goals
- 有限状态机——The finite state machine
- paper:synthesizable finite state machine design techniques using the new systemverilog 3.0 enhancements 之 standard verilog FSM conding styles(二段式)
- paper:synthesizable finite state machine design techniques using the new systemverilog 3.0 enhancements 之 standard verilog FSM conding styles(三段式)
- Finite State Machine
- 译:Finite State Machine Datapath Design, Optimization, and Implementation(一)
- valid states are 'starting running'. the machine is in the 'poweroff' state 的解决
- FSM (Finite State Machine Framework)源码共享
- paper:synthesizable finit state machine design techniques using the new systemverilog 3.0 enhancements之enhanced coding styles
- paper:synthesizable finit state machine design techniques using the new systemverilog 3.0 enhancements之全0/1/z/x的SV写法
- 【Unity】Finite State Machine 有限状态机
- state of the art result for machine learning problems
- vagrant up error: Valid states are 'starting, running'. The machine is in the 'poweroff' state 解决
- Qt: The State Machine Framework 学习
- paper:synthesizable finit state machine design techniques using the new systemverilog 3.0 enhancements之output encoded style with registered outputs(Good style)
- paper:synthesizable finit state machine design techniques using the new systemverilog 3.0 enhancements之fsm summary
- 有限状态机(Finite State Machine)在游戏中的应用和实现
- Finite State Machine
- Are Osworkflow and Activiti based on Finite State Machine(FSM)?
- Finite State Machine library Introduction