-
单循环服务器
-
服务器在同一时刻只能响应一个客户端的请求
-
-
并发服务器模型
-
服务器在同一时刻可以响应多个客户端的请求
-
-
TCP并发
-
多进程
-
多线程
-
IO多路复用
-
为了解决进程或线程阻塞到某个 I/O 系统调用而出现的技术,使进程不阻塞于某个特定的 I/O 系统调用。 优势: 系统开销小,系统不需要建立新的进程或者线程,也不必维护这些线程和进程。
-
-
-
Linux系统IO模型
-
阻塞io
-
scanf getchar fgets gets read recv recvfrom
-
1.可以实现多任务同步(多个事件相互影响) 2.可以节省CPU资源开销,提高执行效率
-
-
-
非阻塞io
-
1. 获取文件描述符属性 2. 为文件描述符添加非阻塞属性 3. 设置文件描述符属性
-
1.可以访问多个IO事件 2.配合轮询操作,浪费CPU资源
-
-
-
信号驱动IO
-
1.实现异步IO操作,节省CPU开销 2.只能针对比较少的IO事件
-
-
多路复用IO
-
select
-
1.监听文件描述符最大个数为1024 2.select监听的文件描述符集合在用户层,需要应用层和内核层互相传递数据(效率低) 3.select需要循环遍历一次才能找到产生的事件 4.select只能工作在水平触发模式(低速模式)无法工作在边沿触发模式(高速模式)
-
-
poll
-
1.poll监测文件描述符不受上限限制 (链表) 2.poll监听的文件描述符集合在用户层,需要内核层向用户层传递数据 3.poll需要循环遍历一次才能找到产生的事件 4.poll只能工作在水平触发模式(低速模式)无法工作在边沿触发模式(高速模式)
-
-
epoll
-
1.epoll创建内核事件表,不受到文件描述符上限限制 (红黑树)o(logn) 2.epoll监听的事件表在内核中,直接在内核中监测事件效率高 3.epoll会直接获得产生事件的文件描述符的信息,而不需要遍历检测 4.epoll既能工作在水平触发模式,也能工作在边沿触发模式
-
-
操作方法: 1)创建文件描述符集合 2)添加关注的文件描述符到集合中 3)监测IO事件
-
函数接口:
-
1.fcntl
-
int fcntl(int fd, int cmd, ... /* arg */ );
-
设置文件描述符属性
-
-
F_GETFL
-
成功返回获得的属性
-
-
F_SETFL
-
设置文件描述符属性
-
-
O_NONBLOCK 非阻塞
-
O_ASYNC 异步方式
-
修改IO属性: 1)获取原有属性 2)增加新的属性 3)设置新的属性
-
-
2.select
-
int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
-
监听文件描述符集合
-
-
void FD_CLR(int fd, fd_set *set); 将fd从文件描述符集合中清除
-
int FD_ISSET(int fd, fd_set *set); (遍历)判断文件描述符fd是否仍在文件描述符集合中
-
void FD_SET(int fd, fd_set *set); 将fd加入文件描述符集合中
-
void FD_ZERO(fd_set *set); 文件描述符集合清0
-
-
3.poll
-
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
-
监听文件描述符集合中的事件
-
-
-
4.epoll模型
-
1)epoll_create 创建epoll文件描述符集合 2)epoll_ctl 添加关注的文件描述符 3)epoll_wait 监控io事件 4)epoll_ctl 从事件集合中删除完成的文件描述符
-
epoll_create
-
int epoll_create(int size);
-
创建一个监听事件表(内核中)
-
-
-
epoll_ctl
-
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
-
在监听事件表中新增一个事件
-
-
-
epoll_wait
-
int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
-
监听事件表中的事件,并将产生的事件存放到结构体数组中
-
-
-
-
-
-