网络编程之多路复用---mutilio

IO多路复用技术

目录

  1. 定义
  2. 作用
  3. 并发与并行
  4. IO模型
  5. 阻塞IO
  6. 非阻塞IO
  7. 信号驱动IO
  8. 并行模型
  9. IO多路复用
  10. select函数详解
  11. select/poll/epoll区别
  12. 作业要求

1. 定义

单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力

2. 作用

应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标的输入、中断信号等等事件,再比如web服务器如nginx,需要同时处理来来自N个客户端的事件。

3. 并发与并行

逻辑控制流在时间上的重叠叫做 并发

并行

而CPU单核在同一时刻只能做一件事情,一种解决办法是对CPU进行时分复用(多个事件流将CPU切割成多个时间片,不同事件流的时间片交替进行)。在计算机系统中,我们用线程或者进程来表示一条执行流,通过不同的线程或进程在操作系统内部的调度,来做到对CPU处理的时分复用。这样多个事件流就可以并发进行,不需要一个等待另一个太久,在用户看起来他们似乎就是并行在做一样。

使用并发处理的成本:

  • 线程/进程创建成本
  • CPU切换不同线程/进程成本 Context Switch 上下文切换 页表,寄存器,缓存
  • 多线程的资源竞争

有没有一种可以在单线程/进程中处理多个事件流的方法呢?一种答案就是IO多路复用。

因此IO多路复用解决的本质问题是在用更少的资源完成更多的事。

4. IO模型

  1. 阻塞IO
  2. 非阻塞IO EAGAIN 忙等待 errno
  3. 信号驱动IO SIGIO 用的相对少(了解)
  4. 并行模型 进程,线程
  5. IO多路复用 select、poll、epoll

1.阻塞IO ===》最常用 默认设置

2.非阻塞IO ===》在阻塞IO的基础上调整其为不再阻塞等待。

在程序执行阶段调整文件的执行方式为非阻塞:

===》fcntl() ===>动态调整文件的阻塞属性

c 复制代码
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );

功能:修改指定文件的属性信息。

参数:fd 要调整的文件描述符

cmd 要调整的文件属性宏名称

... 可变长的属性值参数。

返回值:成功 不一定,看cmd

失败 -1;

eg:修改文件的非阻塞属性:

c 复制代码
int flag ;
flag  = fcntl(fd,F_GETFL,0);  ///获取fd文件的默认属性到flag变量中。
flag  = flag | O_NONBLOCK;    ///将变量的值调整并添加非阻塞属性
fcntl(fd,F_SETFL,flag);       ///将新属性flag设置到fd对应的文件生效。

以上代码执行后的阻塞IO将变成非阻塞方式。

3.信号驱动io

文件描述符需要追加 O_ASYNC 标志。

设备有io事件可以执行时,内核发送SIGIO信号。

1.追加标志

c 复制代码
int flag ;
flag  = fcntl(fd,F_GETFL,0);
fcntl(fd,F_SETFL,flag | O_ASYNC);    

2.设置信号接收者

c 复制代码
fcntl(fd,F_SETOWN,getpid());//常用设置

3.对信号进行捕获

c 复制代码
signal(SIGIO,myhandle);//

4.并行

1.进程

2.线程

5. IO多路复用 ===》并发服务器 ===》TCP协议

3.select循环服务器 ===> 用select函数来动态检测有数据流动的文件描述符

c 复制代码
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);

功能:完成指定描述符集合中有效描述符的动态检测。

该函数具有阻塞等待功能,在函数执行完毕后

目标测试集合中将只保留最后有数据的描述符。

参数:nfds 描述符的上限值,一般是链接后描述符的最大值+1;

readfds 只读描述符集

writefds 只写描述符集

exceptfds 异常描述符集

以上三个参数都是 fd_set * 的描述符集合类型

timeout 检测超时 如果是NULL表示一直检测不超时 。

返回值:超时 0

失败 -1

成功 >0

为了配合select函数执行,有如下宏函数:

c 复制代码
void FD_CLR(int fd, fd_set *set);
int  FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);

select poll epoll的区别

  1. select
c 复制代码
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);

select的调用一般要注意几点:

① readfds等是指针结果参数,会被函数修改...

② 要注意计算nfds...

③ timeout如果为NULL表示阻塞等...

④ select返回-1表示错误...

⑤ Linux的实现中select返回时会将timeout修改为剩余时间...

select的缺点在于:

① 由于描述符集合set的限制...

② 返回的可读集合是个fdset类型...

③ nfds的存在就是为了解决select的效率问题...

  1. epoll
c 复制代码
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

epoll 解决了select和poll的几个性能上的缺陷...

epoll显著提高性能的前提是...

epoll的另外区别是...

作业

使用以上任意一个并发服务器模型,完成如下功能:

  1. 可以向服务器发送一个消息,并在服务器端打印输出该消息的来源ip+port
  2. 将所有的连接终端的个数统计出来

本小节知识总结:io多路复用

IO模型

1.阻塞io 闲等待 让出CPU

2.非阻塞 IO EAGAIN 忙等待errno,不会让出CPU 反复检测io的状态 ,使用fcntl O_NONBLG

3.并行io,进程或者线程,相对多路io而言,比较消耗系统资源

4.多路io,可以处理,单线程或者单进程中,多个阻塞io,select epoll;

多路io复用:由操作系统对io事件进行检测的机制

select:

1.创建集合

2.加入关心的文件描述符;

3.调用select 等待io事件(读或写,大部分情况是读)的到来

4.找出对应的fd',进行读或者写的操作。

5.清除标志位(读写标志位)

epoll

1.创建集合(epoll_wait)

2.加入关心的文件描述符epoll-ctl

3.调用epoll_wait等待io事件(读或者写,大部分情况是读)的到来,并把就绪fd存入就绪集合(rev示例中的rev)

4.在rev集合中找出对应的fd,进行读写操作

对照优缺点

select:最多检测1024个fd;epoll 一般对于服务器而言<5000 fd

select:在检测文件fd式是轮询的方式,一个个文件包描述符询问检测;epoll检测方式:主动上报,通知了才会去:设备通知epoll,epoll通知a.out;

select:在找对应的fd时,需要在原始集合里面(就绪和未就绪在一起)找;epoll:rev集合里(只有就绪的fd)中找出对应的fd;

相关推荐
北极光SD-WAN组网1 小时前
工业互联网时代,如何通过混合SD-WAN提升煤炭行业智能化网络安全
网络·安全·web安全
charlie1145141912 小时前
快速入门Socket编程——封装一套便捷的Socket编程——导论
linux·网络·笔记·面试·网络编程·socket
东风西巷2 小时前
X-plore File Manager v4.34.02 修改版:安卓设备上的全能文件管理器
android·网络·软件需求
liulilittle2 小时前
C++ Proactor 与 Reactor 网络编程模式
开发语言·网络·c++·reactor·proactor
我很好我还能学3 小时前
【计算机网络 篇】TCP基本认识和TCP三次握手相关问题
运维·服务器·网络
苏州向日葵3 小时前
篇五 网络通信硬件之PHY,MAC, RJ45
网络·嵌入式硬件
程序员编程指南4 小时前
Qt 网络编程进阶:WebSocket 通信
c语言·网络·c++·qt·websocket
作业Y4 小时前
第1章第2章笔记
网络
宇宙核5 小时前
【内网穿透】使用FRP实现内网与公网Linux/Ubuntu服务器穿透&项目部署&多项目穿透方案
运维·服务器·网络
bksheng5 小时前
【SSL证书校验问题】通过 monkey-patch 关掉 SSL 证书校验
网络·爬虫·python·网络协议·ssl