Reator模型

概述

Reactor模型是一种设计模式,主要用于处理并发的I/O事件,特别是在网络编程和服务器设计中。

Reacotr模型:

定义

Reactor模式是一种事件驱动的编程模型,主要用于处理I/O事件。它通过在主线程中循环等待I/O事件的发生,并将事件分发到相应的处理程序中。

特点

  1. 单线程:Reactor模式通常在一个单独的线程中运行,负责监听和分发事件。
  2. 事件驱动:当I/O事件(如读、写、连接请求)发生时,Reactor会将事件传递给相应的处理器。
  3. 非阻塞:Reactor模式下,I/O操作是非阻塞的,即不会阻塞主线程的执行。

三个重要组件

Reactor 模型有三个重要的组件:

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

具体流程

  1. 注册读就绪事件和相应的事件处理器;
  2. 事件分离器等待事件;
  3. 事件到来,激活分离器,分离器调用事件对应的处理器;
  4. 事件处理器完成实际的读操作,处理读到的数据,注册新的事件,然后返还控制
    权。

Reactor优点

  • 响应快,不必为单个同步时间所阻塞,虽然 Reactor 本身依然是同步的;
  • 编程相对简单,可以最大程度的避免复杂的多线程及同步问题,并且避免了多线程/进程的切换开销;
  • 可扩展性,可以方便的通过增加 Reactor 实例个数来充分利用 CPU 资源;
  • 可复用性,reactor 框架本身与具体事件处理逻辑无关,具有很高的复用性;

应用场景

适用于需要处理大量并发连接的场景,如Web服务器、数据库服务器等。

代码片段

int main(int argc, char *argv[]) {

	unsigned short port = SERVER_PORT;
	if (argc == 2) {
		port = atoi(argv[1]);
	}

	int sockfd = init_sock(port);

	struct ntyreactor *reactor = (struct ntyreactor*)malloc(sizeof(struct ntyreactor));
	ntyreactor_init(reactor);
	
	ntyreactor_addlistener(reactor, sockfd, accept_cb);
	ntyreactor_run(reactor);

	ntyreactor_destory(reactor);
	close(sockfd);
	

	return 0;
}

来看下init_sock,

int init_sock(short port) {

	int fd = socket(AF_INET, SOCK_STREAM, 0);
	fcntl(fd, F_SETFL, O_NONBLOCK);

	struct sockaddr_in server_addr;
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(port);

	bind(fd, (struct sockaddr*)&server_addr, sizeof(server_addr));

	if (listen(fd, 20) < 0) {
		printf("listen failed : %s\n", strerror(errno));
	}

	return fd;
}

这里设置了非阻塞,fcntl这个函数。

if (reactor == NULL) return -1;
	memset(reactor, 0, sizeof(struct ntyreactor));

	reactor->epfd = epoll_create(1);
	if (reactor->epfd <= 0) {
		printf("create epfd in %s err %s\n", __func__, strerror(errno));
		return -2;
	}

	reactor->events = (struct ntyevent*)malloc((MAX_EPOLL_EVENTS) * sizeof(struct ntyevent));
	if (reactor->events == NULL) {
		printf("create epfd in %s err %s\n", __func__, strerror(errno));
		close(reactor->epfd);
		return -3;
	}

这里是init reactor

int ntyreactor_addlistener(struct ntyreactor *reactor, int sockfd, NCALLBACK *acceptor) {

	if (reactor == NULL) return -1;
	if (reactor->events == NULL) return -1;

	nty_event_set(&reactor->events[sockfd], sockfd, acceptor, reactor);
	nty_event_add(reactor->epfd, EPOLLIN, &reactor->events[sockfd]);

	return 0;
}

这里是reactor监听,使用的事epoll。可以去看下epoll事件。

小结

这次主要写了reactor模型的内容,reactor模型主要包括多路复用器,事件分发器,事件处理器;它的流程包括注册事件,事件分离等待事件,事件到来,分离器调用事件处理对应的处理器;还有reactor的优点,响应快,编程简单,可扩展性强,可复用性等等。其实,也很有意思,有兴趣,一起来学习学习。OK,结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值