在apue阶段对状态机的理解

来源:互联网 发布:php 博客系统 编辑:程序博客网 时间:2024/04/30 09:11

             第一次开博客,第一做APUE的笔记,竟然发现自己的APUE大致的走了一个流程。不过还是毕竟还是收获了一点的东西,那就是有限状态机。

             有限状态机就是系统的所有状态以及在这个几个状态之间的转换,一般在转换状态机的时候就是所谓的,口语化的叫法叫做推动状态机,实现状态机语法一般是switch语句或者是if...else语句,我个人学会了前者。要实现推动状态机,要做的三点1进入状态机条件的初始化2各个状态之间的连贯跳转3必须要有状态机的退出态。比如在两个stdout之间利用消息队列实现收发数据,状态机的状态有

{

 MSG_PATH,

MSG_DATA,

MSG_ERR,

MSG_ROT,

}

要实现这样一个MSG版的状态机它的部分代码如下:

  switch(umsg.mtype)

    {
        case MSG_PATH:   
            uid=getuid();
            gid=getgid();
           stat(umsg.pathmsg.path,&st);
           if(uid==st.st_uid)
          {
             if(st.st_mode&S_IRUSR)
             {
                   umsg.datamsg.mtype=MSG_DATA;
                       break;
              }
               else
                  {
                     umsg.errmsg.mtype=MSG_ERR; 
                     umsg.errmsg.errn=EACCES;
                              break;
                    }
          }
          if(gid==st.st_gid)
          {
              if(st.st_mode&S_IRGRP)
                       {
                         umsg.datamsg.mtype=MSG_DATA;
                            break;
                         }
                     else
                      {
                          umsg.errmsg.mtype=MSG_ERR;
                             umsg.errmsg.errn=EACCES;
                                 break;
                            }
          }
           if(st.st_mode& S_IROTH)
                 {
                       umsg.datamsg.mtype=MSG_DATA;
                              break;
                   }
                else
                  {
                       umsg.errmsg.mtype=MSG_ERR;
                         umsg.errmsg.errn=EACCES;
                            break;
                    }
      case  MSG_DATA:
          file=open(umsg.pathmsg.path, O_RDONLY);                   //open(path)
           if (file<0)
            {
                   umsg.errmsg.errn=errno;
                   umsg.errmsg.mtype=MSG_ERR;
            }
          while(1)
              {
                 umsg.datamsg.datalen= read(file,umsg.datamsg.data,1024);  
                 if(umsg.datamsg.datalen<0)
                 {
                  if(errno==EINTR)
                    continue;
                       umsg.errmsg.errn=errno;
                         umsg.errmsg.mtype=MSG_ERR;
                             break;
                  }
                  if(umsg.datamsg.datalen==0)
                      {        

                                umsg.eotmsg.mtype=MSG_EOT;
                                  break;
                           }
                    if(umsg.datamsg.datalen>0)
                     {
                          ret1= msgsnd(msgid,&umsg,umsg.datamsg.datalen+4,0);                                                     //发送数据到对端。             
                            if(ret1<0)
                             {   
                                 umsg.errmsg.errn=errno;
                                   umsg.errmsg.mtype=MSG_ERR;
                                 }      
                         umsg.datamsg.mtype=MSG_DATA;
                           break;
                       }
                 }
      case MSG_ERR:                           
                      umsg.errmsg.mtype=MSG_EOT;
                             break;
       case MSG_EOT:  break;

       default:
           abort();
           break;
   }
 }
}

 

0 0