多路复用

IO模型介绍

​ 1、阻塞IO:scanf/printf fread/fwrite read/write cin/cout

​ 2、非阻塞IO:recv/send QT中的read、write

​ 3、多路复用IO:使用单进程(单线程)监控多个文件的读写模型,更多情况下使用在网络通信上

​ 除此之外还有信号驱动IO、异步IO

多路复用

​ 使用单进程(单线程)监控多个文件描述符的IO模型,多用于网络编程时服务端程序为若干客户端提供服务。

​ 优点:

​ 1、不需要频繁创建线程、进程和销毁线程、进程,节约时间和资源

​ 2、由于只有单进程(单线程),节约的任务调度时间

​ 缺点:

​ 1、编程难度大

​ 2、单个客户端的请求如果比较耗费时间,其他客户端会有阻塞的感受

​ 因此它只适合并发高但响应时间短的情况,如:web服务器

使用select实现多路复用

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
功能:监控多个文件描述符的读、写、异常等操作
nfds:被监控的文件描述符中最大的描述+1
readfds:需要监控读操作的描述符的集合
writefds:需要监控写操作的描述符的集合
exceptfds:需要监控异常的描述符的集合
timeout:倒计时时间
返回值:发生操作的描述符的个数,超时返回0,出错返回-1
注意:select监控的结果存储在readfds、writefds、exceptfds中
   
void FD_ZERO(fd_set *set);
功能:清空集合

void FD_CLR(int fd, fd_set *set);
功能:从集合中删除描述符

int  FD_ISSET(int fd, fd_set *set);
功能:测试描述符是否在集合中

void FD_SET(int fd, fd_set *set);
功能:从集合中添加描述符

使用过程

​ 设置文件描述符

​ 指定监控范围

​ 设置超时

​ 调用select函数

​ 查看监控结果

select设计不合理的地方

select在使用前,要先设置需要被监控的描述符,然后将其传给select,当有任何一个事件发生时,select将会返回所有的描述符,需要在应用程序自己去遍历检查哪个描述符上有时间发生,效率很低,并且不断在内核态和用户态进行描述符的拷贝,开销很大。

​ 1、所有被监控的描述符都被检查

​ 2、每次调用时都需要重新传递被监控描述符和超时时间

select优点

​ 几乎所有的操作系统都支持,程序的兼容性高

pselect与select的区别

int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
功能:与select基本一致
区别:
    1、超时时间的格式不同
    struct timespec {
               long    tv_sec;         /* seconds */
               long    tv_nsec;        /* nanoseconds */
           };
	  不需要每次都重新设置超时时间,也就是pselect不会修改timeout的参数
	2、pselect在监控时可以通过sigmask设置屏蔽指定的信号

使用poll函数使用多路复用

通过一个可变长的数组解决了select文件描述符受限的问题。数组中元素是结构体,该结构体保存描述符的信息,每增加一个文件描述符就像数组中加 一个结构体,结构体只需要拷贝一次到内核态。

解决了select重复初始化的问题。但轮寻排查问题没有解决。

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
fds:要监控的文件描述符的结构体数组
nfds:数组的长度
timeout:超时时间,单位是毫秒

struct pollfd {
    int   fd;         	要监控的文件描述符
    short events;     	等待监控的事件
        POLLIN			读事件
        POLLPRI			高优先级的读事件
        POLLOUT			写事件
        POLLRDHUP		写操作关闭事件
        POLLERR			错误事件
        POLLHUP			关闭事件
        POLLNVAL		描述符不是个打开的文件
    short revents;    实际发生的事件,也就是返回结果
};

基于epoll的多路复用

epoll:由于轮寻排查所有描述符的效率不高,使服务器并发能力受限。因此epoll采用只返回状态发生变化的文件描述符,便解决了轮寻的问题。

int epoll_create(int size);
功能:创建用于存储被监控描述符的空间
size:要监控的描述符的数量
返回值:代表epoll空间的描述符
    
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
功能:向epoll添加、删除描述符
epfd:epoll_create的返回值
op:
    EPOLL_CTL_ADD	添加描述符
    EPOLL_CTL_MOD	修改要监控的事件
    EPOLL_CTL_DEL	删除描述符
    
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;        传递给内核的数据
};

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
功能:监控描述符,并获取事件发生的描述符
epfd:epoll_create的返回值
events:用于存储监控的结果
maxevents:events数组的长度
timeout:超时时间
返回值:返回事件发生的描述符的数量

与其他多路复用相比的优点

​ 1、文件描述符没有最大限制

​ 2、只需要拷贝一次文件描述符到内核(速度快)

​ 3、只返回事件发生的描述,使用方便

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多路复用器(Multisim)是一种用于电信系统中的设备,其作用是将多个信号通过一个通信通道进行传输。它是一种基于时分多路复用(TDM)技术的设备,能够实现多信号在同一条通信线路上传输。 多路复用器的主要功能是将来自不同源的信号进行整合和分时传输。在多路复用器中,每个信号被分配给一个时间片段,然后按照预定的顺序进行传输。这样,多个信号可以通过共享一个通信通道进行传输,从而提高了通信线路的利用率。 多路复用器能够根据不同的信号特性和需求进行设置。它可以根据信号的带宽、速率和优先级进行调整,并利用时分多路复用技术将多个信号进行合理分配和传输。多路复用器还可以通过差错检测和纠错等技术来提高信号的传输质量。 多路复用器在电信系统中起着重要的作用。它可以将多个电话信号、数据信号或视频信号等进行整合传输,实现了通信资源的共享和最优利用。在现代通信系统中,多路复用器被广泛应用于电话交换机、数据交换机、光纤通信和无线通信等领域。 总而言之,多路复用器是一种用于电信系统中的设备,通过利用时分多路复用技术将多个信号进行整合和分时传输,实现了通信资源的共享和最优利用。它在现代通信系统中起着重要的作用,提高了通信线路的利用率和传输质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值