I/O复用-select函数

以前咱们使用了几种服务器模型,一个是单进程的, 同一时候只能给一个客户端提供服务, 后来咱们使用了多进程, 每一个客户端fork新进程进行业务处理bash

IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程,能够使用一个进程服务多个客户端.服务器

多进程服务模型:

I/O 复用进程模型:

select 实现I/O 复用

select函数原型:函数

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

int select(int maxfd, fd_set * readset, fd_set * writeset, fd_set * exceptset, const struct timeval * timeout);

成功时返回大于0的值, 失败时返回 -1
复制代码

参数解释:ui

maxfd 监视对象文件描述符的数量,举例写法 sever_sock+1
readset 存储的待读取数据文件描述符
writeset 可传输无阻塞数据文件描述符 
exceptset 发生异常的文件描述符
timeout 超时设置
复制代码

select函数返回值, 若是返回大于0的整数, 说明相应数量的文件描述符发生了变化.spa

文件描述符管理

咱们发如今 参数类型上有 fd_set类型,这是什么类型呢? 咱们设置的文件描述符对应的位存储数据格式, 咱们设置这些文件描述符对应位时, 能够使用一些宏实现3d

FD_ZERO(fd_set * fdset) 
将 fd_set 变量的全部位初始化位0

FD_SET(int fd, fd_set * fdset)
在参数 fd_set 指向的变量中注册文件描述符 fd 的信息

FD_CLR(int fd, fd_set * fdset)
从参数 fdset 指向的变量中清除文件描述符 fd 的信息

FD_ISSET(int fd, fd_set * fdset) 
若参数 fdset  指向的变量中包含文件描述符 fd 的信息,则返回真
复制代码

timeval 超时设置结构体

struct timeval 
{
    long tv_sec;  //seconds
    long tv_usec; //microseconds
}
复制代码

示例图

示例代码(回声)

select.ccode

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

#define BUF_SIZE 1024

int main(int argc, char *argv[])
{
    //监视的文件描述符
    fd_set reads, temps;
    struct timeval timeout;
    int result, str_len;
    char buf[BUF_SIZE];

    FD_ZERO(&reads);
    FD_SET(0, &reads); //0 is standard input(console)

    while (1)
    {
        //由于每次select会重置监控句柄,因此赋值给临时
        temps = reads;

        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        // puts 只有事件发生或者发生超时才执行,不然select阻塞
        puts("xxxx");
        result = select(1, &temps, 0, 0, &timeout);

        if (result == -1)
        {
            puts("select() error");
        }
        else if (result == 0)
        {
            puts("nothing event change..time out");
        }
        else
        {
            if (FD_ISSET(0, &temps))
            {
                str_len = read(0, buf, BUF_SIZE);
                printf("message from consle: %s\n", buf);
            }
        }
    }
}
复制代码
gcc select.c -o select

./select
xxxx
123456
message from consle: 123456

xxxx
7890ha
message from consle: 7890ha

xxxx
nothing event change..time out
xxxx
777
message from consle: 777

xxxx
^C
复制代码
相关文章
相关标签/搜索