linux文件IO:select

select

电平触发

#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>

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

在指定的文件描述符准备好I/O之前或超过一定时间限制,select调用会被阻塞

readfds文件描述符集合,监测可读数据
writefds文件描述符集合,监测可写数据
exceptionfds文件描述符集合,监测异常或带外out-of-band数据(适用于套接字)
成功返回时,每个集合只包含对应类型的I/O就绪的文件描述符

n为所有集合中文件描述符的最大值加一

timeout指向timeval结构体

#include<sys/time.h>
struct timeval{
  long tv_sec;  // seconds
  long tv_usec; // microseconds
}

若该参数不为NULL,即使没有文件描述符处于I/O就绪态,select也会在指定时间后返回
若时限中两个都为0,会立即返回,并报告调用时所有事件对应的文件描述符均不可用,且不等待任何后续操作

宏操作

通过宏来管理集合中的文件描述符,允许Unix系统按其希望的方式实现,大多数系统实现为位数组

FD_CLR(int fd, fd_set* set);
FD_ISSET(int fd, fd_set* set);
FD_SET(int fd, fd_set* set);
FD_ZERO(fd_set* set);

FD_ZERO从集合中移除所有文件描述符
FD_SET向集合中添加文件描述符
FD_CLR从集合中移除文件描述符,设计良好的代码从不使用该函数
FD_ISSET测试一个文件描述符是否在集合中,若不存在,返回0

由于文件描述符集合是静态建立的,所以文件描述符数量的上限和文件描述符的最大值均有限制
FD_SETSIZE设定,Linux上值为1024

返回值和错误码

成功时,返回所有集合中I/O就绪的文件描述符的数目,若指定了时限,返回值可能为0
错误时,返回-1,同时errno被设置为下列值

错误码 说明
EBADF 某一个集合中的一个文件描述符非法
EINTR 等待时捕获了一个信号,可以重新发起调用
EINVAL 参数n为负数,或给出的时限不合法
ENOMEM 没有足够的内存完成请求

示例

#include<stdio.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>

#define TIMEOUT 5
#define BUF_LEN 1024

int main(void){
  struct timeval tv;
  fd_set readfds;

  FD_ZERO(&readfds);
  FD_SET(STDIN_FILENO, &readfds);
  tv.tv_sec= TIMEOUT;
  tv.tv_usec= 0;

  int ret= select(STDIN_FILENO+1, &readfds, NULL, NULL);
  if(ret==-1){
    perror("select");
    return 1;
  }else if(!ret){
    printf("%d seconds elapsed.\n", TIMEOUT);
    return 0;
  }

  if(FD_ISSET(STDIN_FILENO, &readfds)){
    char buff[BUF_LEN+1];
    int len= read(STDIN_FILENO, buff, BUF_LEN);
    if(len==-1){
      perror("read");
      return 1;
    }
    if(len){
      buf[len]='\0';
      printf("read:%s\n", buf);
    }
    return 0;
  }
  fprintf(stderr, "this should not happen\n");

  return 0;
}

实现可移植的sleep
微秒级的睡眠机制

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 500;

// sleep for 500 microseconds
select(0,NULL,NULL,NULL, &tv);

Linux提供了高精度的睡眠机制的实现

posted @ 2025-01-22 14:37  sgqmax  阅读(10)  评论(0)    收藏  举报