• 详解select,poll和epoll函数


    select:

    select的原型如下:

    int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

    n是需要监视的最大的文件描述符+1

    select监视的fd分为三类,分别是readfds,writefds和exceptfds。调用select之后会阻塞,直到有描述符就绪,或者超时(timeout指定等待时间,如果设为null则立即返回),函数返回。

    fd_set是一组fd的集合,它用一位来表示一个fd

    可以使用宏操作fd_set:

    fd_set set;
    FD_ZERO(&set);  //clear all bits in set
    FD_SET(3, &set);  //turn on bit 3 in set
    FD_CLR(2, &set);  //clear bit 2 in set
    FD_ISSET(5, &set); //is bit 5 in set on?

    select返回之后,通过遍历fdset,来找到就绪的描述符。

    一个摘自csapp中的例子(只列出了关键代码):

    // read_set is original set, ready_set is working set
    fd_set read_set, ready_set;
    
    listenfd = Open_listenfd(port); // call socket, bind...返回监听描述符
    
    FD_ZERO(&read_set);
    FD_SET(STDIN_FILENO, &read_set)
    FD_SET(listenfd, &read_set)
    
    while(1){
      ready_set = read_set;   // suppose now ready_set : 0001 0001, bit 0 is STDIN_FILENO, bit 4 is listenfd
      select(listenfd+1, &ready_set, NULL, NULL, NULL);  
      if (FD_ISSET(STDIN_FILENO, &ready_set))  // if only STDIN_FILENO is active, now ready_set: 0000 0001
        command();
      if (FD_ISSET(listenfd, &ready_set))  //if only listenfd is active, now ready_set: 0001 0000
        connfd = accept(listenfd, (SA *)&clientaddr, &clientlen);
        echo(connfd);
        close(connfd);  
     }
    
    //这里省略了command(), echo()函数的实现

     select几乎在所有的平台上都支持,跨平台好。缺点主要是单个进程能监视的fd有限制,一般为1024.可通过其他方式调整。

  • 相关阅读:
    第七周作业——用户体验
    第六周作业——Coder和Hacker的区别
    第五周作业——对lua的学习
    产品开发与竞争
    个人项目
    对代码规范的体悟
    第二周作业——浅谈产品同质化应对方法
    第一周作业
    第二次作业
    第一次作业
  • 原文地址:https://www.cnblogs.com/geeklove01/p/8998611.html
Copyright © 2020-2023  润新知