I/O模型

目录

阻塞、非阻塞与同步、异步

阻塞IO,非阻塞IO与同步IO、异步IO

五种IO模型

1,阻塞,同步IO

2,同步,非阻塞模型IO

3,IO多路复用技术

        多路复用IO在web编程中的应用

4,信号驱动IO

5,异步,非阻塞IO


阻塞、非阻塞与同步、异步

        阻塞、非阻塞:说的是进程/线程是否被阻塞,进程/线程被阻塞后,不能执行其他任务,会让

出资源给其他进程/线程使用;

        同步、异步:说的是调用程序一个方法时,是等这个方法返回之后,再进行下一步;还是直

接往下走;

阻塞IO,非阻塞IO与同步IO、异步IO

        阻塞IO,非阻塞IO:说的是应用程序调用IO子系统时,如果没有获得响应,应用程序的线程

是否会被阻塞,不能执行其他任务,让出资源给其他线程使用;

        同步IO、异步IO:说的是应用程序调用操作系统中的IO子系统时,IO子系统是等处理完IO相

关操作之后再返回结果给应用程序,还是不等操作处理完,直接返回一个标识给应用程序,告诉应

用程序:已经收到IO请求,你可以先做其他的事情,如果IO操作处理完了,我会发通知给你(发信

号方式),或者在调用时把后续要做的事情告诉IO子系统,IO子系统帮忙调用处理(回调方式)。

五种IO模型

1,阻塞,同步IO

        阻塞:应用程序调用IO系统之后,在IO系统处理好数据之前,应用程序的线程是阻塞状态,

让渡资源,不能进行其他任务;

        同步:IO系统被调用后,没有立刻返回,而是等数据相关操作处理完成之后,才返回给应用

线程;

2,同步,非阻塞模型IO

        非阻塞:应用程序调用IO系统之后,在IO系统处理好数据之前,应用程序的线程是非阻塞状

态,线程可以继续运行,不停的循环访问内核,看数据是否准备完成;

        同步:IO系统被调用后,没有立刻返回,而是等数据相关操作处理完成之后,才返回给应用

线程;

3,IO多路复用技术

        多路复用技术按分类是阻塞IO,应用线程会阻塞在selector上;

        selector会去轮询数据读取状态,所以多路复用技术在java里面叫NIO(非阻塞IO);

        selector会替代应用程序,轮询一批注册到selector中的文件描述符(套接字,标准输入输

出),只要有部分文件描述符的数据准备就绪,就通知用户程序。

        linux系统的selector由select,poll,epoll方式实现;

        select 的缺点:

       1,每次调用 select,都需要把 fd 集合从用户态拷贝到内核态,这个开销在 fd 很多时会很大;

        2,每次调用 select 都需要在内核遍历传递进来的所有 fd,这个开销在 fd 很多时也很大;

        3,select 支持的文件描述符数量,默认是1024;

        epoll(Linux 2.6内核正式引入,可被用于代替 select 和 poll 系统调用):

        1,内核与用户空间共享一块内存;

        2,通过回调解决遍历问题;

        3,fd 没有限制,可以支撑10万连接;

多路复用IO在web编程中的应用

示例代码:
...
// 监听socketServer的文件描述符
listen_fd = tcp_server_listen(SERV_PORT);
...
// 把上述文件描述符,添加到文件描述符集合中
struct pollfd event_set[INIT_SIZE]; 
event_set[0].fd = listen_fd; 
event_set[0].events = POLLRDNORM;
...
for (;;) {
 //调用poll函数,轮询文件描述符集合,进行事件检测
    if ((ready_number = poll(event_set, INIT_SIZE, -1)) < 0) { 
        error(1, errno, "poll failed "); 
    }


    if (event_set[0].revents & POLLRDNORM) { 
        socklen_t client_len = sizeof(client_addr); 
        //socketServer监听,如果有链接事件,创建socket链接描述符
        connected_fd = accept(listen_fd, (struct sockaddr *) &client_addr, &client_len); 
        //把socket链接描述符,添加到描述符集合中;
        for (i = 1; i < INIT_SIZE; i++) { 
            if (event_set[i].fd < 0) { 
                event_set[i].fd = connected_fd; 
                event_set[i].events = POLLRDNORM; 
                break; 
            } 
        }
    }

    // 链接描述符,读写数据
    for (i = 1; i < INIT_SIZE; i++) {
        if (event_set[i].revents & (POLLRDNORM | POLLERR)) { 
            if ((n = read(socket_fd, buf, MAXLINE)) > 0) { 
                if (write(socket_fd, buf, n) < 0) { 
                    error(1, errno, "write error"); 
                } 
            } else if (n == 0 || errno == ECONNRESET) { 
                close(socket_fd); event_set[i].fd = -1; 
            } else { 
                error(1, errno, "read error"); 
            }
        }
    }
}

4,信号驱动IO

5,异步,非阻塞IO

        应用程序,发出IO调用后,非阻塞,执行其他任务;

        内核,处理完数据之后,把数据从内核空间,拷贝到用户空间,再发信号给应用程序;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值