#Header1_HeaderTitle{ font-size:50px }

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 ('\n' == c)
                {
                    continue;
                }
                printf("the input is %c\n", c);
                if ('q' == c)
                {
                    break;
                }
            }
        }
        else       /**< 超时 */
        {
            cout << "time out" << endl;
            continue;
        }
    }
    return 0;
}

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

posted @ 2020-04-28 09:56  墨麟非攻  阅读(613)  评论(0编辑  收藏  举报