网络模块-reactor模式

背景

高性能服务器的开发需要考虑到3点:I/O事件、定时事件、信号。
对于多并发的场景,我们应该如何高效的管理和操作多个IO端口,日常有两种高效的事件处理模型:reactor和proactor,值得我们借鉴。以下讲的是reactor。高性能网络服务器的必备技术之一。

介绍

 reactor模式中文翻译为反应堆,是一种事件驱动机制,简单来说是对io多路复用上的封装,用于管理多个io端口。可以及时对io数据进行处理
 reacor中心思想是将所有的事件注册到多路复用器上,等待I/O事件的到来,调用事先注册的事件(这些注册的事件也叫做回调函数),到对应的处理器中。

reactor的3种模式

  1. 单线程模式
  2. 多线程模式(单reactor)
  3. 多线程模式(多reactor)

 这篇文章我们主要介绍最简单的单线程模式
 reactor内部由3个组件组成:多路复用器+ 事件分发器 + 事件处理器。

小黑板:

  • 多路复用器:由操作系统提供,在linux一般就是select、poll、epoll等系统调用
  • 事件分发器:将多路复用器中返回的就绪事件分到对应的处理函数中
  • 事件处理器:处理特定事件的处理函数

在这里插入图片描述

实现一个单线程的reactor(epoll)

reactor重 将每个事件封装成一个结构体,而后将这些结构体以下写出reactor一些重要的部分,用于封装epoll模型

单独事件结构体

  • 描述

用于管理每一个IO事件

  • 代码
struct ntyevent {
	int fd;		// sockfd
	int events;		// event事件,即触发的条件
	void *arg;	// 参数,避免有需要参数传递
	int (*callback)(int fd, int events, void *arg);	// 回调函数,当触发时使用什么函数处理
	
	int status;	// 状态,用于判断该事件是否删除
	char buffer[BUFFER_LENGTH];	// 接收或需要发送的数据
	int length;		// 实际接收或发送数据的长度
	long last_active;	// 最后活跃的时间,用于关闭一段时间内不活跃的事件
};

reactor总表

  • 描述

用于控制整个reactor事件,由所有的io事件组成,这里我们用指针对其集合,当然也可以使用数组或红黑树

  • 代码
struct ntyreactor {
	int epfd;	// 为epoll_create创建的红黑树节点
	struct ntyevent *events;	// 所有事件的结合
};

reactor事件增删改

// 将信息与事件进行绑定
void nty_event_set(struct ntyevent *ev, int fd, NCALLBACK callback, void *arg) {

	ev->fd = fd;
	ev->callback = callback;
	ev->events = 0;
	ev->arg = arg;
	ev->last_active = time(NULL);

	return ;
}
// 事件添加
int nty_event_add(int epfd, int events, struct ntyevent *ev) {

	struct epoll_event ep_ev = {0, {0}};
	ep_ev.data.ptr = ev;
	ep_ev.events = ev->events = events;

	int op;
	if (ev->status == 1) {
		op = EPOLL_CTL_MOD;
	} else {
		op = EPOLL_CTL_ADD;
		ev->status = 1;
	}

	if (epoll_ctl(epfd, op, ev->fd, &ep_ev) < 0) {
		printf("event add failed [fd=%d], events[%d]\n", ev->fd, events);
		return -1;
	}

	return 0;
}

// 事件删除
int nty_event_del(int epfd, struct ntyevent *ev) {

	struct epoll_event ep_ev = {0, {0}};

	if (ev->status != 1) {
		return -1;
	}

	ep_ev.data.ptr = ev;
	ev->status = 0;
	epoll_ctl(epfd, EPOLL_CTL_DEL, ev->fd, &ep_ev);

	return 0;
}

总结

优点

  • 响应快:不必为单个同步时间所阻塞
  • 可扩展性:可以方便的通过增加reactor个数来充分利用CPU资源
  • 可复用性:reactor框架本身与具体事件处理逻辑无关,具有很高的复用性
  • 编程相对简单:可以最大程度的避免复杂的多线程和同步的问题

缺点

当前线程出现了一个长时间的IO数据读写,则会影响其他的client

使用到reactor的开源库

使用到reactor模式的开源代码:nginx、libevent

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值