您的位置:首页 > 其它

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐