i/o多路复用笔记
1、用户空间和内核空间
操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也可以访问底层硬件设备。为了保护用户进程不能直接操作内核,保证内核的安全,操作系统将虚拟空间划分为两部分,一部分是内核空间,一部分是用户空间。
2、进程切换
内核挂起当前正在cpu上运行的进程,并恢复以前挂起的某个进程的执行。
- 保存处理机上下文,包括程序计数器和其它寄存器。
- 更新PCB信息
- 把进程的PCB移入到相应的队列,如就绪或阻塞队列
- 选择另一个进程执行,并更新PCB
- 更新内存管理的数据结构
- 恢复上下文
3、进程阻塞
正在执行的进程,由于期待某些事件的发生,比如IO,自动执行阻塞原语,进入阻塞状态。这是一种主动行为,只有运行中的进程才可以切换到阻塞状态。在阻塞状态的进程是不占用CPU资源的。
4、I/O模式
标准I/O,数据会先被拷贝到操作系统的内核缓冲区,然后才会从操作系统的内核缓冲区拷贝到应用程序的地址空间。
linux有五种网络模式:
- 阻塞I/O
- 非阻塞I/O
- I/O多路复用
- 信号驱动I/O(signal driven i/o,不常用)
- 异步I/O
1、阻塞I/O
用户进程调用recvfrom系统调用,进程进入阻塞状态,等待数据准备好,数据会从内核拷贝到用户内存,然后内核返回结果,用户进程解除block状态,重新运行。
2、非阻塞I/O
用户进程调用read操作,如果数据还没准备好,内核立刻返回error,用户进程不会阻塞。用户进程可以通过反复调用read操作轮询来获得数据。
3、I/O多路复用
I/O multiplexing,也就是select、poll、epoll,也可以被称为event driven I/O。好处是单个进程可以处理多个网络I/O,原理就是select、poll、epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达时,就通知用户进程。
用户进程调用了select,整个进程会被block,同时,kernel会监听所有负责的socket,当有一个socket的数据准备好了,select会返回,用户进程再调用read操作,将数据从内核拷贝到用户进程。如果处理的并发连接数不是很高,使用select、poll、epoll的服务端性能不一定比使用multi-threading + blocking IO的服务端性能好。I/O多路复用时,每一个socket,一般设置为非阻塞模式。
5、I/O多路复用
select
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
select函数监视的文件描述符分3类,分别是readfds、writefds、exceptfds。调用select函数会阻塞,直到有描述符就绪或者超时,函数返回。当select函数返回后,可以通过遍历fdset,找到就绪的描述符。
select可以良好的跨平台。缺点是单个进程能够监视的文件描述符的数量存在最大限制。在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制。
poll
int poll(struct pollfd *fds, unsigned int nfds, int timeout)
struct pollfd {
int fd;
short events; // requested events to watch
short revents; //returned events witnessed
}
pollfd结构包含了要监视的event和发生的event,不再使用select『参数-值』传递的方式。pollfd没有最大数量限制,但仍需要轮询返回的pollfd来获取就绪的文件描述符。随着监视的文件描述符数量的增长,效率也会线性下降。
epoll
和select、poll相比,epoll更加灵活,没有描述符的限制。epoll使用一个文件描述符管理多个描述符,将用户进程的文件描述符事件存放在内核的一个事件表中,这样在用户空间和内核空间只需copy一次。
int epoll_create(int size)
创建一个epoll的句柄,size用来告诉内核监听的数目。size并不是限制了epoll所能监听的最大描述符个数,只是对内核初始分配内部数据结构的一个建议。
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
函数对指定描述符fd执行op操作。op取值由三个宏表示:添加EPOLL_CTL_ADD,删除EPOLL_CTL_DEL,修改EPOLL_CTL_MOD。epoll_event告诉内核需要监听什么事。
typedef union epoll_data {
void *ptr;
int fd;
_uint32_t u32;
_uint64_t u64;
} epoll_data_t;
struct epoll_event {
_uint32_t events;
epoll_data_t data;
};
//epoll events
EPOLLIN:表示对应的文件描述符可读(包括对端SOCKET正常关闭)
EPOLLOUT: 表示对应的文件描述符可写
EPOLLPRI: 表示对应的文件描述符有紧急数据可读(带外数据)
EPOLLERR: 表示对应的文件描述法发生错误
EPOLLHUP: 表示对应的文件描述法被挂起
EPOLLET: 设置为边缘触发
EPOLLONESHOT: 只监听一次事件,当监听完这次事件后,如果还需要监听这个socket,需要再次把这个socket加入epoll
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
参数events表示内核得到的事件的集合。maxevents告知内核这个events有多大,取值不能大于创建epoll_create()时的size。参数timeout时超时时间(ms,0表示立刻返回,-1表示不确定,也有说法是永久堵塞)。该函数返回需要处理的事件数目,如返回0表示已超时。
6、epoll工作模式
两种:LT(level trigger), ET(edge trigger)。缺省是LT。
- LT: 当epoll_wait检测到描述符事件发生时,将此事件通知应用程序。
应用程序可以不立即处理该事件
,下次调用epoll_wait时,会再次响应应用程序并通知。 - ET: 当epoll_wait检测到描述符事件发生时,将此事件通知应用程序。
应用程序必须立即处理该事件
,下次调用epoll_wait时,不会再次通知此事件。
LT是缺省工作模式,支持block和non-block socket。ET是高速工作模式,只支持non-block。
7、总结
在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描。epoll事先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait()时便得到通知。epoll监视的描述符的数量不受限制,它所支持的FD上限是系统最大可打开文件数目。
i/o多路复用笔记的更多相关文章
- 7.24 IO多路复用和协程代码笔记
1. 复习 # !/usr/bin/env python # !--*--coding:utf-8 --*-- # !@Time :2018/7/23 11:49 # !@Author TrueNew ...
- Java IO学习笔记六:NIO到多路复用
作者:Grey 原文地址:Java IO学习笔记六:NIO到多路复用 虽然NIO性能上比BIO要好,参考:Java IO学习笔记五:BIO到NIO 但是NIO也有问题,NIO服务端的示例代码中往往会包 ...
- Java IO学习笔记七:多路复用从单线程到多线程
作者:Grey 原文地址:Java IO学习笔记七:多路复用从单线程到多线程 在前面提到的多路复用的服务端代码中, 我们在处理读数据的同时,也处理了写事件: public void readHandl ...
- python学习笔记-(十四)I/O多路复用 阻塞、非阻塞、同步、异步
1. 概念说明 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可 ...
- HTTP/2笔记之流和多路复用
零.前言 本部分将讲解HTTP/2协议中对流的定义和使用,其实就是在说HTTP/2是若何做到多路复用的. 一.流和多路复用的关系 1. 流的概念 流(Stream),服务器和客户端在HTTP/2连接内 ...
- python 学习笔记12(事件驱动、IO多路复用、异步IO)
阻塞IO和非阻塞IO.同步IO和异步IO的区别 讨论背景:Linux环境下的network IO. 1.先决条件(几个重要概念) 1.1.用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32 ...
- python学习笔记10--协程、IO、IO多路复用
本节内容 一.协程 1.1.协程概念 1.2.greenlet 1.3.Gevent 1.4.协程之爬虫 1.5.协程之socket 二.论事件驱动与异步IO 三.IO 3.1.概念说明 3.2.IO ...
- io多路复用,select,笔记
一下代码,是摘自大王的博客,(http://www.cnblogs.com/alex3714/)我自己有加了些注释. 1 2 3 #_*_coding:utf-8_*_ 4 5 __author__ ...
- STM32学习笔记——OLED屏
STM32学习笔记--OLED屏 OLED屏的特点: 1. 模块有单色和双色可选,单色为纯蓝色,双色为黄蓝双色(本人选用双色): 2. 显示尺寸为0.96寸 3. 分辨率为128*64 4. ...
随机推荐
- echart报表插件使用笔记(二)--按月统计
按月统计注冊人数 java类: package com.spring.controller; import java.io.IOException; import java.sql.Connectio ...
- 【u246】卫星照片
Time Limit: 1 second Memory Limit: 64 MB [问题描述] 农夫 John 正在研究他的农场的卫星照片.照片为一个R (1<= R <= 75) 行C ...
- PWA之Web 应用清单
原文 简书原文:https://www.jianshu.com/p/5c96242188e8 大纲 1.什么是Web 应用清单 2.“清单文件”:Web App Manifest 规范的应用 3.we ...
- Python 语法细节(Python 2.x 与 Python 3.x 语法差异)
Language differences and workarounds 查询 Python 语言版本: >> import sys >> sys.version '3.5.2 ...
- jquery 多选框 checkbox 获取选中的框
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- js javascript正则
var re = new RegExp("^[0-9]$"); 或者 var re2 = /^\d$/;//这个好像兼容性更好,比如你在上面的语句里面写\d,就总是返回false, ...
- [Angular Directive] Build a Directive that Tracks User Events in a Service in Angular 2
A @Directive is used to add behavior to elements and components in your application. This makes @Dir ...
- Windows 查看硬盘ID(diskpart命令)
使用diskpart命令Win+R键运行cmd,进入命令行界面:1.diskpart2.list disk 查看有几块硬盘3.select disk 0 选择第一块硬盘4.detail disk 显示 ...
- 关于ulimit -a中需要修改的两个值
以root用户运行 ulimit -a 命令,其中有两个参数分别为: open files和max user processes 修改方法: vi /etc/security/limits.co ...
- 【hdu 1067】Gap
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission( ...