网络编程之多路复用---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;

相关推荐
油丶酸萝卜别吃1 小时前
nginx配置代理服务器
运维·网络·nginx
伯恩bourne2 小时前
MIME(多用途互联网邮件扩展)
网络·网络协议
运维行者_3 小时前
使用Applications Manager进行 Apache Solr 监控
运维·网络·数据库·网络安全·云计算·apache·solr
蝸牛ちゃん3 小时前
大型软件需求变更管理:从混沌到可控的工程化实践
网络·需求分析·变更管理·需求变更
Mr_Xuhhh5 小时前
传输层协议TCP(3)
运维·服务器·网络·网络协议·tcp/ip·http·https
lsnm6 小时前
【LINUX网络】HTTP协议基本结构、搭建自己的HTTP简单服务器
linux·运维·服务器·c语言·网络·c++·http
SKYDROID云卓小助手8 小时前
三轴云台之控制信号解析与执行
运维·服务器·网络·人工智能·信号处理
板鸭〈小号〉8 小时前
Linux网络基础(一)
linux·网络·智能路由器
kebeiovo8 小时前
I/O多路复用特性与实现
网络
wanhengidc11 小时前
云手机选哪个比较好用?
服务器·网络·安全·游戏·智能手机