muduo源码分析——EventLoop

本文详细分析了muduo库中的核心类EventLoop,包括其成员变量、构造过程和wakeup机制。EventLoop是Reactor模式的核心,文章探讨了loop循环、wakeup socket的使用以及queueInLoop的功能。同时,文中提到了EventLoop在flamingo代码中的应用,指出wakeup socket的释放可能存在内存泄漏问题,但在muduo框架中由于特定的使用方式,该问题并未实际引发问题。最后,文章讨论了doPendingFunctors中利用std::vector和unique_lock确保线程安全的策略。
摘要由CSDN通过智能技术生成

先简单说一下,因为我参考的是flamingo的代码,会和muduo有一点点出入,但是基本是差不多,因为前者是基于后者开发的,可能有一点点改动。

EventLoop是muduo里比较核心的类吧,因为它是实现Reactor模式的核心,什么是Reactor模式,其实很多文章和书籍都有讲,我也打算抽空写一篇博客,来总结下自己的心得,至少现在没有总结,哈哈~~。

其实如果认真读一下EventLoop里的Loop循环的话,就可以很好的了解Reactor模式了,
不过还是先从成员开始吧!

成员

    private:
		typedef std::vector<Channel*> ChannelList;

		bool                                looping_; /* atomic */
		bool                                quit_; /* atomic and shared between threads, okay on x86, I guess. */
		bool                                eventHandling_; /* atomic */
		bool                                callingPendingFunctors_; /* atomic */
		const std::thread::id               threadId_;//对应的线程id号
		Timestamp                           pollReturnTime_;
		std::shared_ptr<Poller>             poller_;//初始化默认创建EpollPoller
        std::shared_ptr<TimerQueue>         timerQueue_;
        int64_t                             iteration_;

        SOCKET                              wakeupFd_;          //TODO: 这个fd什么时候释放?,在EventLoop被析构的时候会释放,但是确实没有找到相应调用析构的代码。
		// unlike in TimerQueue, which is an internal class,
		// we don't expose Channel to client.
		std::shared_ptr<Channel>            wakeupChannel_;
	
		// scratch variables
		ChannelList                         activeChannels_;//epoll事件会被压入这个vector
		Channel*                            currentActiveChannel_;//被用来遍历,上一行的vector

		std::mutex                          mutex_;//用来保护下面那行的执行
		std::vector<Functor>                pendingFunctors_; // Guarded by mutex_

		Functor                             frameFunctor_;
	};

注意!为了减少行数,我把#indef win32给删掉了。
先简单说一下4个bool型的变量:
looping_代表是否开始循环。
quit_代表是否退出。
eventHandling_代表是否在处理事件。
callingPendingFunctors_代表是否在处理被push的待执行函数(此处后面会说一下)。

说一下这个东西

SOCKET      wakeupFd_;//TODO: 这个fd什么时候释放?,在EventLoop被析构的时候会释放,但是确实没有找到相应调用析构的代码。

这个socket使用来唤醒的,有一个wakeup函数,会向这个socket写入一个uint64_t one = 1;来唤醒它。不过这个释放,确实没有找到具体的实现位置,它会在EventLoop被析构的时候被释放,但是muduo代码里好像没有析构EventLoop的代码,而且EventLoopThread和EventLoopThreadPool持有EventLoop的方式是使用EventLoop*,也不是使用智能指针,不会自动清理,其实算是一个会造成内存泄漏的问题点吧。不过muduo框架也没有重复的去创建EventLoop的过程,而是在程序一开始运行就初始化好了,所以也不会造成别的问题吧,只要客户代码不反复的去创建TcpServer,那就不会出现问题,所以这是需要注意的一点!在flamingo里面,chatServer,你可以就把它当作是TcpServer,是使用单例模式创建的,所以就避免了这个问题。
后续做一个小测试,反复创建看看效果如何!

后面也没有特别需要解释说明的成员了,基本在注释里就写好了。

构造

我们来看看它的构造

EventLoop::EventLoop()
: looping_(false),
quit_(false),
eventHandling_(false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值