记录自己对EventLoop和性能问题处理的一点心得

时间:2023-02-15 06:57:13

1、EventLoop

这里说的EventLoop不是指某一个具体的库或是框架,而是指一种程序实现结构。这种结构多是基于IO多路转接的API(select、poll、epoll之类)以reactor模型,实现IO事件处理、timer和异步事件处理。具体常见的库有libev、libevent,以及陈硕(@bnu_chenshuo)的muduo。这些库或是框架基本的原理流程都类似,区别都是在API接口功能和多平台支持之上。这里就不具体的对此进行展开讨论了,接下来说说自己对EventLoop的一点理解,欢迎各路大侠拍砖。

先简单抛出一个自己的结论:现在的程序服务基本上都可以使用EventLoop的结构来驱动。

其原因是需求都近乎于类似,基本上都要处理IO事件进行消息收发与外部进行通讯、都要实现timer来进行定时、都要发起一些异步处理过程。而这些都可以用EventLoop进行抽象。对这些功能实现了统一的抽象实现之后,在此之上实现基础的TcpServer、TcpClient、UDP Peer就方便的多了,在往上进一步加上各自的业务逻辑,就形成了各种Server、客户端。可以说核心的结构都是类似,细分的差别就体现在内存管理、包收发控制(拥塞控制)、并发模型设计、系统架构Scale和健壮容错能力方面。

如下图所示

记录自己对EventLoop和性能问题处理的一点心得

虚线框中既是基本的EventLoop的组件功能了。功能丰富一点库会在APP Sever/APP Client中实现诸如http server/http request之类的功能了,比如陈硕的muduo,或是精简一点,TCP Server/TCP Client/UDP Peer都没做,只实现了IO Event Handle、Timer、Async Event,比如libev。自己分析了muduo实现,模仿其API,也用C杜撰了一套精简的实现,实现了上述框架的的功能,APP的部分具体实现了RTSP Server/RTSP Request功能,也在公司里用的挺好,这里要推荐一下muduo,其API是自己见过功能的库中使用最方便的一个(也可能是自己孤陋寡闻,没见过更牛掰的),也促成自己重新造了一个*。

2,性能问题问题

自己遇到的性能问题主要是体现在CPU使用率上。在自己最近做的项目中,遇到过三次CPU使用率过高的问题,但问题原因各不相同。这里记录一下

1) 一次是因为软件使用的一个第三方SDK中默认开启了软件解码运算而导致的。发现问题原因所在首先要进行度量,以确定具体是在哪里耗CPU明显。此时自己使用的是process explorer工具(windows)中线程查看功能,其可以具体的查看一个进程中各个线程的运行情况,包括CPU使用率和调用栈。对此很直接找到问题的元凶。之后联系对应厂商开发人员,对SDK进行修改,关闭默认解码操作,提供开关控制后解决。

2)一次是因为检测了IO句柄上的无用的write事件,而导致代码流程空转所致。经过实际验证,发现该问题可控,当停止所有的网络功能之后,CPU使用率立马回复正常,就基本确定于网络功能有关。解决该问题仍然是先进行度量,这次的度量工具是VS中的性能分析工具,用其对各个函数的调用情况进行采样,很轻松的发现那些函数调用的次数比较多,就直接定位到问题点,经过分析后将write事件监测改为按需进行后解决问题。

3)第三次是因为代码bug在一个不常见的处理分支中而陷入了死循环。同样先进行分析发现该现象不可控,整个程序已经完全不能相应更多的控制操作。遂用VS以调试方式将程序跑起来,将问题复现后,将程序暂停运行后恢复运行,重复几次之后,发现每次暂停时执行流程都陷入在同一个地方,就基本确定代码在这个地方陷入死循环了。仔细地分析了代码,结合实际外部触发条件后,找到了bug所在。修改代码重新进行验证测试,问题解决。

~~~~ end ~~~