代码改变世界

Unix I/O模型

2012-08-09 09:32  康杜  阅读(207)  评论(0编辑  收藏  举报

在Unix系统中,I/O模型基本上可以分为5种,分别是

  • Blocking I/O
  • Nonblocking I/O
  • I/O Multiplexing (select, poll)
  • Signal-drvien I/O (SIGIO)
  • Asynchronous I/O (the POSIX aio_functions)

 

推荐大家阅读这里 http://www.cs.huji.ac.il/course/2004/com1/Exercises/Ex4/I.O.models.pdf

为了让自己更深入地理解各I/O模型,我用C语言写前面3种。

1. Blocking I/O

#define BUFFERSIZE 4096
//如果是一个输入,一个输出的话,用Blocking的IO没有问题                          
int main(void){
  char buf[4096];
  while (1){
    //输入                                                                      
    read(STDIN_FILENO, buf, BUFFERSIZE);
    //输出                                                                      
    printf("%s", buf);
  }
}

 

2. Nonblockign I/O

 

#include "../apue.h"
#include <unistd.h>
#include <fcntl.h>
#define BUFFERSIZE 256
int main(void){
  char buf[BUFFERSIZE];
  while (1){
    //输入                                                                      
    int fl = fcntl(STDIN_FILENO, F_GETFL, 0); //取得文件描述符的标志            
    fcntl(STDIN_FILENO, F_SETFL, fl | O_NONBLOCK); //设置该进程的标准输入为非阻\
塞的                                                                            
    read(STDIN_FILENO, buf, BUFFERSIZE);
    //输出                                                                      
    printf("我在等待你的输入");
  }
}

 

3. Multiplexing I/O

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/poll.h>
#include <sys/time.h>
#include <unistd.h>
#define BUFFERSIZE 4096
int main(int argc, char **argv){
  char buf[BUFFERSIZE];
  int fd,i;
  fd_set fds;
  struct pollfd pfds[2];
  fd = open(argv[1], O_RDONLY);
  while(1){
    pfds[0].fd = 0;
    pfds[0].events = POLLIN;
    pfds[1].fd = fd;
    pfds[1].events = POLLIN;
    poll(pfds, 2, -1);
    //主要是这句语句起了作用,让程序不调用同步的read函数                                                                                      
    if (pfds[0].revents & POLLIN){
      i = read(0, buf, 1024);
      if (!i){
        printf("stdin closed\n");
        return 0;
      }
      write(1, buf, i);
      return 0;
    }
    if (pfds[1].revents & POLLIN){
      i = read(fd, buf, 1024);
      if (!i){
        printf("file closed\n");
        return 0;
      }
      //Write to stdout                                                                                                                       
      write(1, buf, i);
    if (pfds[0].revents & POLLIN){
      i = read(0, buf, 1024);
      if (!i){
        printf("stdin closed\n");
        return 0;
      }
      write(1, buf, i);
      return 0;
    }
    if (pfds[1].revents & POLLIN){
      i = read(fd, buf, 1024);
      if (!i){
        printf("file closed\n");
        return 0;
      }
      //Write to stdout                                                                                                                       
      write(1, buf, i);
    }
   }
}