• Linux下I/O复用 Select与Poll


    Select

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

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

    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);

    调用select 将受到阻塞,必须等到指定的文件描述符就绪可进行I/O,或者等到一个指定的事件限额过去。

    此调用所监视的文件描述符分为三种事件类型,每个等待不同的事件。readfds中的文件描述符是准备读取的;writefds 分组中的文件描述符是准备写入数据的; exceptfds 分组的中的文件描述符是用于查看是否有异常发生或紧急数据可用。这三个分组可以是NULL,在此情况下 select() 将无法监视相应的事件。

    此调用返回后,每个分组只会包含就绪可进行I/O的文件描述符。

    第一个参数 n 等于任何分组中最高编号的文件描述符的值加1。

    timeout 参数是一个指向 timeval 结构的指针,该结构的定义如下:
    struct timeval {

         long tv_sec; 

         seconds long tv_usec; 

         microseconds

    };

    如果此参数不是 NULL,则 select() 调用将在 tv_sec 秒与 tv_usec 微秒之后返回,即使尚无任何文件描述符就绪可进行I/O。如果 timeout 的这两个值都被设为零,则此调用会立即返回,报告此调用进行的时候是否有任何事件等待处理,但是不会等待其后的任何事件。

    fd_set writefds;
    FD_ZERO(&writefds);
    FD_SET(fd,&writefds); //将fd加入分组
    FD_CLR(fd,&writedfds); //从分组移除fd 
    FD_ISSET(fd,&writefds); //测试特定文件描述符是否已就绪 
     1 #include <stdio.h>
     2 #include <sys/time.h>
     3 #include <sys/types.h>
     4 #include <unistd.h>
     5 
     6 #define TIMEOUT 5
     7 #define BUF_LEN 1024    
     8 
     9 int main()
    10 {
    11     struct timeval tv;
    12     fd_set readfds;
    13 
    14     FD_ZERO(&readfds);
    15     FD_SET(STDIN_FILENO, &readfds);
    16 
    17     tv.tv_sec = TIMEOUT;
    18     tv.tv_usec = 0;
    19 
    20     ret = select (STDIN_FILENO+1, &readfds, NULL,NULL,&tv);
    21 
    22     if (FD_ISSET (STDIN_FILENO, &readfds)) {
    23         char buf[BUF_LEN+1];
    24         int len = read(STDIN_FILENO, buf, BUF_LEN);
    25 
    26         buf[len] = 0;
    27         printf("read:%s
    ",buf);
    28     }
    29 }


    poll

    #include <sys/poll.h> 

    int poll (struct pollfd *fds, unsigned int nfds, int timeout);

    struct pollfd {
        int fd; //文件描述符

        short events; //所要查看的事件

        short revents; //返回所目击事件
    };

    每个 pllfd 结构可用于制定一个要查看的文件描述符。每个pollfd结构的 events 字段是该文件描述符所要查看事件的位掩码,用户可以设定此字段。而 revents 字段则是该文件描述符所目击事件的位掩码,内核会在返回时设定此字段。

    有效事件包括:
    POLLIN 有数据可供读取
    OLLRDNORM 有一般数据可供读取
    POLLRDBAND 有优先数据可供读取
    POLLPRI 有紧急数据可供读取
    POLLOUT 写入操作将不受阻塞
    POLLWRNORM 写入一般数据将不受组阻塞
    POLLWRBAND 写入优先数据将不受阻塞
    POLLMSG 有SIGPOLL消息可用
    POLLER 所指定的文件描述符发生错误
    POLLHUP 所指定的文件描述符发生挂起事件
    POLLNVAL 所指定的文件描述符无效

    例子:

     1 #include <stdio.h>
     2 #include <unistd.h>
     3 #include <sys/poll.h>
     4 
     5 #define TIMEOUT 5
     6 
     7 int main()
     8 {
     9     struct pollfd fds[2];
    10     int ret;
    11 
    12     fds[0].fd = STDIN_FILENO;
    13     fds[0].events = POLLIN;
    14 
    15     fds[1].fd = STDOUT_FILENO;
    16     fds[1].events = POLLOUT;
    17 
    18     int a;
    19     //scanf("%d",&a);
    20     ret = poll(fds,2,TIMEOUT*1000);
    21 
    22     if (!ret) {
    23         perror("poll");
    24         return 1;
    25     }
    26 
    27     if (!ret) {
    28         printf("%d seconds elapsed. 
    ", TIMEOUT);
    29         return 0;
    30     }
    31 
    32     if (fds[0].revents & POLLIN) 
    33         printf("stdin is readable
    ");
    34 
    35     if (fds[1].revents & POLLOUT)
    36         printf("stdout is writable
    ");
    37     scanf("%d",&a);
    38     return 0;
    39 }
  • 相关阅读:
    uiautomator2自动化测试
    APP性能测试(电池电量、流量、CPU、内存)
    python虚拟环境搭建
    unittest报错(return self._request(command_info[0], url, body=data))
    python pip错误处理
    adb 实用命令
    大数据学习(一)
    windows 下Virtualenv搭建mysql环境
    python奇怪毛病集合
    python作业
  • 原文地址:https://www.cnblogs.com/nicganon/p/3761789.html
Copyright © 2020-2023  润新知