您的位置:首页 > 运维架构 > Linux

linux高编IO-------有限状态机编程原理(mycpy)

2016-04-12 16:31 435 查看
有限状态机:负责解决复杂流程

简单流程:如果一个程序的自然流程是结构化的

复杂流程:如果一个程序的自然流程不是结构化的

网络协议:一般不是简单流程



=================================================================================================

用有限状态机思想实现mycpy



==============================================================================================

范例:

/**********************
*有限状态机实现mycpy
* *******************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

//两个设备
#define  TTY1 "/dev/tty11"
#define  TTY2 "/dev/tty12"
//
#define  BUFSIZE    1024
//有限状态机的四种状态
enum
{
STATE_R = 1 ,//读
STATE_W ,    //写
STATE_EX ,   //异常
STATE_T      //终止
};

//有限状态机结构体
struct fsm_st
{
int state ; //有限状态机状态
int sfd ;   //源文件
int dfd ;   //目标文件
int len ;   //读取文件的长度
int pos ;   //文件位置
char buf[BUFSIZE];//存储读取的数据
char *strerr ;//出错原因
};

//有限状态机驱动
static void fsm_driver(struct fsm_st *fsm)
{
int ret ;
switch (fsm->state)
{
//1.读
case STATE_R:
fsm->len = read(fsm->sfd , fsm->buf ,BUFSIZE);
//1.1没有数据
if(fsm->len == 0)
fsm->state = STATE_T ;
//1.2读失败
else if(fsm->len < 0)
{
//判断真错假错
if(errno == EAGAIN)
fsm->state = STATE_R ;
else
{
fsm->strerr = "read()";
fsm->state = STATE_EX ;
}
}
//1.3读成功后,推动写
else
{
fsm->pos = 0;
fsm->state = STATE_W;
}
break ;
//2.写
case STATE_W:
ret = write(fsm->dfd , fsm->buf+fsm->pos , fsm->len);
//2.1写失败
if(ret < 0)
{   //判断真错假错
if(errno == EAGAIN)
fsm->state = STATE_W ;
else
{
fsm->strerr = "write()";
fsm->state = STATE_EX ;
}
}
//2.2写成功
else
{
fsm->pos += ret ;
fsm->len -= ret ;
if(fsm->len == 0)
fsm->state = STATE_R ;
else
fsm->state = STATE_W ;

}
break ;
//3.异常
case STATE_EX:
perror(fsm->strerr);
fsm->state = STATE_T ;
break ;
//4.终止
case STATE_T :

break;
default :
abort();
break;
}
}

//修改设备状态(都为NONBLOCK方式),并为每个设备初始化有限状态机
static void relay(int fd1 ,int fd2)
{
int fd1_save , fd2_save ;
struct fsm_st fsm12,fsm21;
//1.保存设备初始状态
fd1_save = fcntl(fd1,F_GETFL);
//2.设置设备的NONBLOCK状态
fcntl(fd1 ,F_SETFL ,fd1_save | O_NONBLOCK);

fd2_save = fcntl(fd2 , F_GETFL);
fcntl(fd2,F_SETFL,fd2_save | O_NONBLOCK);
//3.初始化有限状态机
fsm12.state = STATE_R ;
fsm12.sfd = fd1 ;
fsm12.dfd = fd2 ;

fsm21.state = STATE_R ;
fsm21.sfd = fd2 ;
fsm21.dfd = fd1 ;
//4.start推动状态机运行
while(fsm12.state != STATE_T || fsm21.state != STATE_T)
{
fsm_driver(&fsm12);
fsm_driver(&fsm21);

}
//5.设备状态恢复
fcntl(fd1 , F_SETFL , fd1_save);
fcntl(fd2 , F_SETFL , fd2_save);

}
int main()
{
int fd1, fd2 ;
//用户可以使用BLOCK方式或者NONBLOCK方式打开文件
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);
//修改文件状态
relay(fd1 , fd2);

close(fd2);
close(fd1);
exit(0);
}


运行结果:在终端运行可执行程序

ctl+alt+F11 和ctl+alt+F12 ,在两个字符终端间分别输入数据,会在相对的字符终端显示数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: