select函数学习,监听标准输入

select函数是什么

select函数可以将多个文件描述符集中到一起统一监视,监视项分为三类(接收,传输,异常)。为避免阻塞,该函数也有超时时间参数。

/* Check the first NFDS descriptors each in READFDS (if not NULL) for read
   readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
   (if not NULL) for exceptional conditions.  If TIMEOUT is not NULL, time out
   after waiting the interval specified therein.  Returns the number of ready
   descriptors, or -1 for errors.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int select (int __nfds, fd_set *__restrict __readfds,
		   fd_set *__restrict __writefds,
		   fd_set *__restrict __exceptfds,
		   struct timeval *__restrict __timeout);
__nfds:监视对象文件描述符数量,即监视范围。只需将需要监视的最大的文件描述符加1即可,加1是因为文件描述符从0开始。
__readfds:关注接收事件的fd_set文件描述符组
__writefds:关注传输事件的fd_set文件描述符组
__exceptfds:关注异常事件的fd_set文件描述符组
__timeout:超时时间,防止陷入阻塞
返回值:发生错误返回-1,超时返回0。
       因发生关注的事件返回时,返回大于0的值,该值为发生关注事件的文件描述符数

多个文件描述符的集合用fd_set类型设置,fd_set的最左端的位表示文件描述符0,当该位值为1时表示监视该文件描述符。
有相关宏定义用于操作该变量。

/* Access macros for `fd_set'.  */
FD_SET(int fd, fd_set *fdsetp)	在参数fdsetp指向的变量中注册文件描述符fd的信息
FD_CLR(int fd, fd_set *fdsetp)	在参数fdsetp指向的变量中清除文件描述符fd的信息
FD_ISSET(int fd, fd_set *fdsetp)	若fdsetp中有fd的信息,则返回true
FD_ZERO(fd_set *fdsetp)	设置fdsetp变量的所有位为0

2.select函数怎么用

Created with Raphaël 2.3.0 select参数设置(设置文件描述符,指定监视范围,设置超时) 调用select函数 查看调用结果,后处理

注意:
1.在调用select函数后, tv_sec以及tv_usec的值会被替换为超前剩余时间, 循环中需注意
2.在调用select函数后, 除发生变化的文件描述符对应位外, 其他位将初始化为0

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

#define BUF_SIZE 100

int main(){
    fd_set reads, temps;
    FD_ZERO(&reads);
    FD_SET(0, &reads);//0为标准输入文件描述符, 监视标准输入

    struct timeval time;
    //time.tv_sec = 3;//在调用select函数后, tv_sec以及tv_usec的值会被替换为超前剩余时间
    //time.tv_usec = 0;

    int str_len;
    int res;
    char buf[BUF_SIZE];

    while (1){
        temps = reads;//在调用select函数后, 除发生变化的文件描述符对应位外, 其他位将初始化为0, 这是为了记住初始值
        time.tv_sec = 3;//在调用select函数后, tv_sec以及tv_usec的值会被替换为超前剩余时间
        time.tv_usec = 0;
        res = select(1, &temps, NULL, NULL, &time);
        if(res == -1){
            printf("select error\n");
            break;
        } else if(res == 0){
            printf("select timeout\n");
        } else{
            if(FD_ISSET(0, &temps)){
                str_len = read(0, buf, BUF_SIZE);
                buf[BUF_SIZE] = 0;
                printf("message from console:%s", buf);
            }

        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值