• select函数的使用


    select函数是 I/O 复用中非常重要的一个函数,属于并发编程的。它能够监视我们需要监视的文件描述符的变化情况–读、写或者异常

    1. 函数原型

    #include <sys/select.h>
    
    int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set*errorfds,struct timeval *timeout

    select将文件描述符放入一个集合,成为文件描述符集fd_set

    2. 参数

    1. maxfdp是一个整数值,集合中文件描述符的范围,所有文件描述符最大值 + 1

    2. fd_set *readfds。读文件描述符集,关心文件描述符的读变化

    3. fd_set *writefds。写文件描述符集,关心文件描述符的写变化

    4. fd_set *errorfds。监视文件错误异常

    5. struct timeval* timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态。

        第一:NULL,即不传入时间结构,就是将select至于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变换为止;

        第二:0秒0毫秒,就变成了一个纯粹的非阻塞函数,不管文件描述符有无变化,立刻返回。无变化返回0, 有变化返回一个正值

        第三:timeout的值大于0,select在timeout时间内阻塞,超时时间之内有事件到来就返回,否则立即返回,返回值同第二条

    3. 返回值

    负值:select错误

    正值:某些文件可读、可写或者出错

    0:等待超时,没有可读、可写或者出错的文件

    4. 相关宏

    FD_CLR(inr fd,fd_set* set);        用来清除描述词组set中相关fd的位
    
    FD_ISSET(int fd,fd_set *set);    用来测试描述词组set中相关fd的位是否为真
    
    FD_SET(int fd,fd_set*set);        用来设置描述词组set中相关fd的位
    
    FD_ZERO(fd_set *set);             用来清除描述词组set的全部位

    struct timeval代表时间值,一个是秒数、另一个微妙

    #include <sys/time.h>
    struct timeval
    {
          time_t tv_sec;        //seconds 秒
          time_t tv_usec;        //microseconds 微秒,1000000 微秒 = 1秒
    };

    5. select_example.cpp

    Linux下监控键盘上是否有数据到来

    #include <sys/time.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <assert.h>
    
    #include <unistd.h>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int keyboard;
        int ret,i;
        char c;
        fd_set readfd;
        struct timeval timeout;
    
        keyboard = open("/dev/tty",O_RDONLY | O_NONBLOCK);
        assert(keyboard > 0);
    
        while (1)
        {
            timeout.tv_sec = 5;
            timeout.tv_usec = 0;
            FD_ZERO(&readfd);
            FD_SET(keyboard,&readfd);        
    
            ret = select(keyboard + 1, &readfd, NULL, NULL, &timeout);
            if (ret == -1)             /**< 错误情况 */
            {
                cout << "error" << endl;
            }
            else if (ret)              /**< 返回值大于0,有数据到来 */
            {
                if (FD_ISSET(keyboard, &readfd))
                {
                    i = read(keyboard, &c, 1);
                    if ('
    ' == c)
                    {
                        continue;
                    }
                    printf("the input is %c
    ", c);
                    if ('q' == c)
                    {
                        break;
                    }
                }
            }
            else       /**< 超时 */
            {
                cout << "time out" << endl;
                continue;
            }
        }
        return 0;
    }

    由于是C++文件,因此采用g++ -o select_example select_example.cpp进行编译

  • 相关阅读:
    0909 谈谈我对操作系统的理解
    实验四 主存空间的分配和回收模拟
    12.03进程调度实验点评
    实验三进程调度实验
    实验二 作业调度模拟程序编写
    实验一 DOS命令解释程序的编写
    0909 随笔第一季
    实验四 主存空间的分配和回收模拟
    实验三 进程调度模拟实验
    实验二 作业调度模拟实验
  • 原文地址:https://www.cnblogs.com/gezhuangzhuang/p/12792135.html
Copyright © 2020-2023  润新知