select()函数 的学习

select()的介绍 全是拷贝的如下文章:

https://www.cnblogs.com/wenqiang/p/5508541.html

select()函数的用例代码摘录如下文章:

https://blog.csdn.net/aiwoziji13/article/details/6688916

1. select函数简介

  select一般用在socket网络编程中,在网络编程的过程中,经常会遇到许多阻塞的函数,网络编程时使用的recv, recvfrom、connect函数都是阻塞的函数,当函数不能成功执行的时候,程序就会一直阻塞在这里,无法执行下面的代码。这是就需要用到非阻塞的编程方式,使用 selcet函数就可以实现非阻塞编程。
selcet函数是一个轮循函数,即当循环询问文件节点,可设置超时时间,超时时间到了就跳过代码继续往下执行。

下面是select的函数原型:

 /* According to POSIX.1-2001 */
#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

参数介绍:

第一个参数:int nfds--->是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1

第二个参数:fd_set *readfds---->用来检查一组可读性的文件描述符。

第三个参数:fd_set *writefds---->用来检查一组可写性的文件描述符。

第四个参数:fd_set *exceptfds---->用来检查文件文件描述符是否异常

第五个参数:sreuct timeval *timeout--->是一个时间结构体,用来设置超时时间。该参数是NULL,表示是阻塞操作

select函数的返回值 :

负值:select错误
正值:表示某些文件可读或可写
0:等待超时,没有可读写或错误的文件

下面是一些跟select() 一起使用的函数及结构的作用

void FD_ZERO(fd_set *set);         //清空一个文件描述符的集合
void FD_SET(int fd, fd_set *set);  //将一个文件描述符添加到一个指定的文件描述符集合中
void FD_CLR(int fd, fd_set *set);  //将一个指定的文件描述符从集合中清除;
int  FD_ISSET(int fd, fd_set *set);//检查集合中指定的文件描述符是否可以读写

struct timeval 结构体可以精确到秒跟毫秒。用于设置阻塞时间;如果其成员设置为0,表示不阻塞,立即返回。

 struct timeval {
    time_t            tv_sec;     /* seconds */
    suseconds_t    tv_usec;    /* microseconds */
};

下面是使用select()函数的一个例子:

// test select()
#include<stdio.h>
#include<string.h>
#include <fcntl.h>
#include <assert.h> 

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

int main()
{
    int fd = open("/dev/tty", O_RDONLY|O_NONBLOCK);
    assert(fd>0);

    int ret = 0;
    fd_set fd_set;
    struct timeval timeout;

    while(1) {
        FD_ZERO(&fd_set);
        FD_SET(fd, &fd_set);

        timeout.tv_sec = 5; //set timeout time
        timeout.tv_usec = 0;

        ret = select(fd+1, &fd_set, NULL, NULL, &timeout);
        if(-1 == ret) {
           printf("select failure\n");
           return -1;
        } else if(0 == ret) {
           printf("time out \n");
        }

        if(FD_ISSET(fd, &fd_set)) {
            char ch;
            int num = read(fd, &ch, 1);
            //getchar();
            if('\n' == ch) continue;
            else if ('q' == ch) break;
            else printf("ch = %c\n", ch);
        }
    }

    close(fd);
    return 0;
}

 

posted @ 2018-11-26 16:03  靖意风  Views(254)  Comments(0Edit  收藏  举报