【libevent 】libevent 多线程实现高并发
当你看到这篇文章时,想必你对libevent已经有了足够的了解,笔者在此就不多做描述了,直接进入正题。
1.起因
最近在做Redis中间件,目标实现集群管理、分布式数据处理、高性能。由于在某些情况下,单个节点的Redis性能可能无法满足需求,并且单个机器的内存大小是受限制的。如果采用中间件的方式管理多个Redis实例,不仅可以避免单点机器内存不够用的情况,也能使性能得到大幅提升。经过Redis中间件数据分片后,各个Redis实例可以同时处理读写请求,所以比单线程的Redis实例要快很多。在这里,中间件起到数据转发及管理的功能,特别是数据转发这一块,对中间件的处理能力要求比较高,在高并发情况下也能保证数据正常处理,不能影响业务使用。
2.实现
要实现高性能的服务端网络程序,基本上是异步处理网络IO+多线程。关于异步处理网络IO,网络上现成的库有很多,如果你喜欢动手,自己封装也行。不过我还是建议大家使用已经造好的、成熟稳定的轮子。在这里我比较推荐使用libevent,这个库相对来说比较成熟,使用起来也简单。
3.架构图
在这个架构模型中,我们开启了N个线程,每个线程中包含一个event_base对象,他们都是在自己的线程中工作。何时派发工作给这些工作线程,则由一个专门的AcceptThread线程来完成。这个线程负责接受客户端的连接,接受成功后会将该连接分配给工作线程。在这里我们采用均衡分配的方式,让每个线程处理的连接数是趋于相等的。
4.代码流程
首先要让libevent支持多线程,需要加上一段代码,这段代码只需要执行一次
#ifdef WIN32
evthread_use_windows_threads();
#else
evthread_use_pthreads();
#endif
第一步:创建一个WorkThread线程池,每个线程对象中包含一个event_base对象,由于没有事件的话event_dispatch函数会退出,我们可以在里面注册一个永久的定时器事件,这样每个工作进程就不会退出。这个时候的状态是:等待外部给这个工作线程添加事件。
第二步:主线程监听端口,接受客户端连接。每到来一个连接就形成一个ConnectContext的结构,然后分配到一个工作线程去完成读写操作。这个过程不需要我们去加锁,libevent内部已经完成了这个操作。我们只需要在AcceptThread中派发任务给工作线程就可以了。
第三步:没了,按照这个架构,大部分代码就是写处理数据的代码了。
原文链接:https://blog.csdn.net/loydia/article/details/78683558
libevent框架:
1、创建 event_base
2、创建 事件event -->常规事件/带缓冲的事件
3、将事件 添加到base上
4、循环监听事件满足
5、释放 base
1、struct event_base *base = event_base_new();
2、event_new()/buffevent_socket_new();
3、event_add(struct event_base *base);
4、event_base_disptch(base);
5、event_base_free(base);