Chinaunix首页 | 论坛 | 博客
  • 博客访问: 688619
  • 博文数量: 240
  • 博客积分: 3616
  • 博客等级: 大校
  • 技术积分: 2663
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-21 23:59
文章分类

全部博文(240)

文章存档

2013年(6)

2012年(80)

2011年(119)

2010年(35)

分类: LINUX

2010-10-21 14:29:34



#include
#include
#include
#include
#include
int main(void)
{
 int fds[2];//定义int的数组,由于存放两个文件描述符
 char buf[7];
 int i,rc,maxfd;
 unsigned int tmp1,tmp2,tmp3;
 fd_set inset1,inset2 //定义两个fd_set的变量,具体类型见内核原代码,一定要遵循内核函数规则,不要
                      //乱定义变量,依葫芦画瓢就可以了.
 struct timeval tv; // 定义一个结构体,类型为struct timeval,名称为tv
 if((fds[0]=open("hello1",O_RDWR |O_CREAT,0666))<0)//打开一个文件,并且判断是否出错
 {
  perror("open hello1");
 }
 if((fds[1]=open("hello2",O_RDWR|O_CREAT,0666))<0)
 {
  perror("open hello2");
 }
 if((rc=write(fds[0],"hello!\n",7)))//向hello1这个文件中写hello !, 长度为7个字节
 {
  printf("rc=%d\n",rc);//打印write返回的长度
 }
 lseek(fds[0],0,SEEK_SET);//移动文件的读写指针,让起从文件头开始,这不很重要
 printf("the fds[0] is %d\n",fds[0]);//打印文件描述符
 printf("the fds[1] is %d\n",fds[1]);
 maxfd=fds[0]>fds[1]?fds[0]:fds[1];//判断这两个文件描述符中的最大值
 FD_ZERO(&inset1);
 FD_SET(fds[0],&inset1);
 FD_ZERO(&inset2);
 FD_SET(fds[1],&inset2);//见后面的注释
 tv.tv_sec=2;
 tv.tv_usec=0;//时间设置为2s
 
 while(FD_ISSET(fds[0],&inset1)||FD_ISSET(fds[1],&inset2))
 { 
  tmp3=select(maxfd+1,&inset1,&inset2,NULL,&tv);
  printf("the tmp3 is %d\n",tmp3);
  if(select(maxfd+1,&inset1,&inset2,NULL,&tv)<0)
  {
   perror("select");
  } 
  else
  { 
   tmp1=FD_ISSET(fds[0],&inset1);
   printf("the tmp1 is %d\n",tmp1);
   //if(FD_ISSET(fds[0],&inset1))
   if(tmp1)
   {
    rc=read(fds[0],buf,7);
    if(rc>0)
    {
     buf[rc]='\0';
     printf("read:%s\n",buf);
    } 
    else
    {
     perror("read"); 
    }
   }
   tmp2=FD_ISSET(fds[1],&inset2);
   printf("the tmp2 is %d\n",tmp2);
   //if(FD_ISSET(fds[1],&inset2))
   if(tmp2)
   { 
    //printf("the inset2 is :%d\n",inset2);
    rc=write(fds[1],buf,7);
    if(rc>0)
    {
     buf[rc]='\0';
     printf("rc=%d,write:%s\n",rc,buf); 
    } 
    else
    {
     perror("write"); 
    }
    sleep(5);
   } 
   
  }
 }
 
 exit(0);
}
/*-----------------------------------------------------
1.select函数说明:
前面的fcntl函数解决了文件的共享问题,接下来该来处理IO复用的情况
IO处理的模型有5种:
阻塞IO模型:若所调用的IO函数没有完成相关的功能就会使进程挂起,直到
相关数据到才会出错返回.
非阻塞模型:当请就的IO操作不能完成时,则不让进程睡眠.而且返回一个错误.
IO多路转接模型:如果请求的IO操作阻塞,且它不是真正阻塞IO,而是让其中的
一个函数等待,在这期间,IO还能进行其他的操作.
信号驱动IO模型:通过安装一个信号处理程序,系统可以自动捕获特定的信号的到来,
从而启动IO.
异步IO模型:当一个描述符已准备好,可以启动IO时,进程会通知内核.现在,
并不是所有的系统都支持这种模型.
2.select函数格式
1)所需要的头文件:
#include
#include
#include
2)函数原型
int select(int numfds,fd_set *readfs,fd_set *writefds,fd_set *exeptfds,
struct timeval *timeout)
3)输入参数
numfds:需要检查的号码最大的文件描述符加1
readfds:由select()监视的读文件描述符集合
writefds:由select()监视的写文件描述符集合
exeptfds:由select()监视的异常处理文件描述符集合
timeout
NULL:永远等待,知道捕捉到信号或文件描述符已准备好为止.
具体值:struct timeval类型的指针,若等待为timeout时间还没有文件描述符准备好,
就立刻返回.
0:从不等待,测试所有指定的描述符并立即返回.
4函数返回值
成功:准备好的文件描述符
-1:出错.
3.selsect 文件描述符处理函数
FD_ZERO(fd_set *set)  //清除一个文件描述符集
FD_SET(int fd,fd_set *set)   //将一个文件描述符加入文件描述符集中
FD_CLR(int fd,fd_set *set)   //将一个文件描述符从文件描述符中清除
FD_ISSET(int fd,fd_set *set) //测试该集中的一个给定位是否有变化
一般来说,在使用select函数之前,首先使用FD_ZERO和FD_SET来初始化文件描述符
集,在使用了select函数时,可循环使用FD_ISSET测试描述符集,在执行完对相关
文件描述符后,使用FD_CLR来清除描述符集.
4.struct timeval类型的指针,该结构体如下所示:
struct timeval
{
 long tv_sec ; //second
 long tv_unsec ; //and microseconds 
 
}
--------------------------------------------------------*/
阅读(596) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~