网络编程——多路复用相关函数(select、pselect、poll、epoll)

基础概念

多路复用:
  使用一个进程(且只有一个主线程)同时监控若干个文件描述符的读写,这种读写模式叫做多路复用
  多用于TCP服务端,用于监控若干个客户端的连接和数据的收发
  优点:不需要频繁地创建进程、销毁进程,从而达到节约内存资源、时间资源,也能避免进程之间的竞争、等待
  缺点:单个客户端的任务不能耗时太长,否则其它客户端就会感知到。
  适合并发量高、任务量短小的情景,例如:web服务器

select

fd_set 是文件描述符的集合,要通过以下函数进行操作
    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);
        功能:清空集合

#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
	功能:监控多个文件描述符的读、写、异常操作
	nfds:被监控的文件描述符中最大+1
	readfds:监控读操作的文件描述符集合
	writefds:监控写操作的文件描述符集合
	exceptfds:监控异常操作的文件描述符集合
	timeout:设置超时时间
		NULL    一直阻塞,直到某个文件描述符发生变化
		大于0   等待超时时间,超时后返回 0
		00毫秒   非阻塞  
	返回值:监控到发生相关操作的文件描述符的个数,超时返回 0,错误返回-1

注意:
  readfds、writefds、exceptfds 这三个参数既是输入也是输出,也就是说调用select时这三个集合里面需要存放着被监控的文件描述符,当函数因为监控的文件描述符发生变化而返回时,发生变化的文件描述符会存在集合中,没发生变化的就删除掉了

select设计不合理的地方
  1、每次调用select时都需要重新向它传递被监控者的集合
  2、调用结束后若想要直到哪些文件描述符发生了相关操作,需要把所有的被监控的文件描述符都测试一边

select的优点
  它是最早启用多路复用的函数,几乎所有的操作系统都支持,程序的兼容性高

pselect

#include <sys/select.h>

int pselect(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, const struct timespec *timeout,const sigset_t *sigmask);
	功能:与select大致相同
	区别:
		1、超时时间的类型不同,pselect的精度更高
		2、pselect的timeout。既是输入也是输出,可以返回剩余的时间,但是select只是输入
		3、pselect监听时可以通过sigmask参数设置想要在监听时屏蔽的信号,可以保证pselect的监听不被信号干扰

poll

#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);
	功能:和select相同
	fds:pollfd结构体数组
		struct pollfd {
			int   fd;         // 被监听的文件描述符 输入
			short events;     // 要监听的事件       输入
			short revents;    // 实际监听到的事件   输出
				POLLIN      普通优先级的读事件
				POLLPRI     高优先级的读事件
				POLLOUT     普通优先级的写事件
				POLLRDHUP   对方socket关闭
				POLLERR     错误事件
				POLLHUP     对方挂起事件
				POLLNVAL    非法发描述符
		};
	nfds:数组的长度
	timeout:超时时间
	返回值:监听到发生相关操作的描述符的个数,超时返回 0,错误返回-1

epoll

#include <sys/epoll.h>

int epoll_create(int size);
	功能:创建一个epoll对象,该对象可以保存被监控的描述符
	size:epoll对象能保存的描述符的数量
	返回值:创建成功的epoll对象

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
	功能:控制epoll对象,添加、删除描述符,修改监听事件
	epfd:epoll对象的描述符,即epoll_create的返回值
	op:
		EPOLL_CTL_ADD       添加socket文件描述符
		EPOLL_CTL_DEL       删除socket文件描述符
		EPOLL_CTL_MOD       修改要监控的事件
	fd:
		想要操作的socket文件描述符
	event:
		想要监控的事件,参考poll的事件,添加、修改时有用,删除时给 NULL
	返回值:成功返回 0,失败返回 -1

int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
	功能:监控文件描述符,并返回产生事件的文件描述符
	epfd:epoll对象的描述符,即epoll_create的返回值
	events:输出型参数,用于获取产生事件的文件描述符
	maxevents:可以返回的最大的事件数量
	timeout:超时时间
	返回值:事件发生的描述符的数量

epoll的优点:
	1、只需要拷贝一次描述符,不需要重复赋值
	2、会把发生变化的文件描述符返回,因此不需要遍历全部的文件描述符即可
	3、编程结构简洁
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值