select ()函数的使用与原理问题

1.使用
定义集合
fd_set rdset;
清空集合
FD_ZERO( & rdset)
绑定与清除
FD_SET(fdr, &rdset ) , or FD_SET(STDIN_FILENO, &rdset);
FD_CLR ( fdr , &rdset) , or FD_CLR( STDIN_FILENO ,& rdset) ;
select ()监听
int ret = select ( maxfd+1, &rdset ,NULL , NULL , &timeval ) & timeval为监听间隔
最后一个参数 为 NULL为0 ,为一个数 ,对应了不同的iO模型
struct timeval用来代表时间值,有两个成员,一个是秒数,另一个是毫秒数。 若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;第三,timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回

判断响应
FD_ISSET( STDIN_FILENO,&rdset) or FD_ISST( fdr , &rdset) ;

//chat1.c 
   #include <stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/time.h>
#include<stdlib.h>
#include<strings.h>
#include<string.h>
int main(int argc ,char *agrv[])
{

    if ( argc < 3 )
    {
        perror("error");
    }
    int fdr = open(agrv[1],O_RDONLY);
    int fdw = open(agrv[2],O_WRONLY);
    printf("I am chat1 fdr = %d,fdw = %d\n",fdr,fdw);
    char buf[128]= {0};
    fd_set rdset;
    int ret ; 
    struct timeval timeout;

    while( 1 )
    {
        FD_ZERO(&rdset);
        FD_SET(STDIN_FILENO,&rdset);
        FD_SET(fdr,&rdset);
        bzero(&timeout,sizeof(timeout));
        timeout.tv_sec=3;
        ret = select (fdr+1,&rdset,NULL,NULL,&timeout);
        if ( ret>0 )
        {
            if((FD_ISSET(STDIN_FILENO,&rdset)))
            {
                memset(buf,0,sizeof(buf));
                ret =read(STDIN_FILENO,buf,sizeof(buf));
                if (0==ret)
                {
                    printf("borken up\n");
                    break;
                }

                write(fdw,buf,strlen(buf)-1);
            }
            if (FD_ISSET(fdr,&rdset))
            {
                memset(buf,0,sizeof(buf));
                ret= read(fdr,buf,sizeof(buf));
                if(0 ==ret)
                {
                    printf("bye\n");
                    break;
                }

                printf("%s\n",buf);
            }

        }
        else{
            printf("timeout \n");
        }
    }

    close(fdr);
    close(fdw);
    printf("Hello world\n");
    return 0;
}
//chat2.c 
#include <stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/time.h>
#include<stdlib.h>
#include<strings.h>
#include<string.h>
int main(int argc ,char *agrv[])
{
    if ( argc < 3 )
    {
        perror("error");
    }
    int fdw = open(agrv[1],O_WRONLY);
    int fdr = open(agrv[2],O_RDONLY);
    printf("I am chat1 fdr = %d,fdw = %d\n",fdr,fdw);
    char buf[128]= {0};
    fd_set rdset;
 
    while(1)
    {
        FD_ZERO(&rdset);
        FD_SET(STDIN_FILENO,&rdset);
        FD_SET(fdr,&rdset);
        int ret = select(fdr+1,&rdset,NULL,NULL,NULL);
        if (FD_ISSET(STDIN_FILENO,&rdset))
        {
            memset(buf, 0 , sizeof(buf));
            read(STDIN_FILENO,buf,sizeof(buf));
            write(fdw,buf,strlen(buf)-1);
            
        }
        if (FD_ISSET(fdr,&rdset))
        {
            memset(buf,0,sizeof(buf));
            ret= read(fdr,buf,sizeof(buf));
            if (0==ret)
            {
                printf("byebye\n");
                break;
            }
            printf("%s\n",buf);
        }
    }
    return 0 ;
}
  1. select 的原理
    int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);
    对于select来说最终的两个字是轮询,不断的轮询所有的描述符,来判断是否需要响应,到达并发的目的。
    最大监听数量为1024 ,大多数应用场景下,可能只有少数的进程是活跃的而其他的 进程是活跃的,所以呢,这种轮询是一种浪费
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值