【sylar服务器】IO资源管理调度

目录
    IO资源管理调度
    1. 1、IO管理调度
      1. 1.1、事件枚举
      2. 1.2、socket事件上下文类
      3. 1.3、IO管理的函数
      4. 1.4、类中私有成员
      5. 1.5、总结
      6. 1.6、致谢

    [1]sylar服务器 https://github.com/sylar-yin/sylar

    IO资源管理调度

    • 基于TCP/UDO实现服务器与客户端之间的连接,后台需要时刻接收来自客户端的连接信息,在高并发的环境,如何去实现对各个套接字的监控,sylar服务器使用的epoll方法,在网络套接字管理类,则是对epoll进行的一个封装。
    1、IO管理调度
    • soceket管理类基于epoll实现对网络连接的管理,整个类分为三部分,事件枚举,socket事件上下文类,IO管理函数。
    1.1、事件枚举
    ```c enum Event { // 无事件 NONE = 0x0, // 读事件(EPOLLIN) READ = 0x1, // 写事件(EPOLLOUT) WRITE = 0x4, }; ``` - Event这里实现对对IO事件属性的设置,在套接字登记和消息返回时,evnent可以用来指明消息属性
    1.2、socket事件上下文类
    struct FdContext {//socket上下文类
            typedef Mutex MutexType;
            struct EventContext {//事件上线文类
                Scheduler* scheduler = nullptr;
                Fiber::ptr fiber;
                std::function<void()> cb;
            };
            EventContext& getContext(Event event);//获取事件上下文类
            void resetContext(EventContext& ctx);//重置事件上下文
            void triggerEvent(Event event);//触发事件
            EventContext read;//读事件上下文
            EventContext write;//写事件上下文
            int fd = 0;//套接字句柄
            Event events = NONE;//当前事件
            MutexType mutex;//事件的mutex
        };
    • sokcet用于配置一个套接字使用的相关信息(回调函数,读写类型)。io类基于epoll方法实现,当一个套接进入io类进行注册时,socket则将该套接字进行封装为类,并提供对事件的处理方法。
    • EventContext类
      • 这个结构体中,封装关于回调函数的相关信息。每个套接字会配套一个回调函数,事件响应后调用回调函数,EventConetxt则指定该函数设置的协程和调度器信息(默认IO调度)
      • 附:这个sylar服务器底层是基于协程实现的调度器
    1.3、IO管理的函数
    //threads:底层调度器需要的线程数量,user_calller:是否立即调度,name:调度器名称
    	IOManager(size_t threads = 1, bool use_caller = true, const std::string& name = "");
        //fd:套接字,event:事件类型,cb:套接字对应的回调函数
    	int addEvent(int fd, Event event, std::function<void()> cb = nullptr);
    	//fd:删除的套接字句柄,event:事件类型
        bool delEvent(int fd, Event event);
        bool cancelEvent(int fd, Event event);
        bool cancelAll(int fd);
        static IOManager* GetThis();                                                          
    protected:
    	//io类继承于schedule类,io类用来重写,使得在首次调度时就启动监听套接字函数
        void idle() override;
    	//扩张调度器容纳的数量。
        void contextResize(size_t size);
        bool stopping(uint64_t& timeout);
    1.4、类中私有成员
    //epoll句柄
        int m_epfd = 0;
    	//原子量,用来记录其中的事件总数
        std::atomic<size_t> m_pendingEventCount = {0};
        /// IOManager的Mutex
        RWMutexType m_mutex;
        /// socket事件上下文的容器
        std::vector<FdContext*> m_fdContexts;
    1.5、总结
    - 对于系统资源类型对象,应集中管理接受调度。在sylar服务器中,底层利用协程来运行函数的,同时在设计了一个调度器来登记每一个运行的函数,并进行相关调度。在进行设计时,对于复用资源性对象,进行封装处理,并设计一个管理类,来对是西安资源的调度 - 设计时,一定要注意并发的情况。在io管理类中,接收一个套接字,就需要做相关的信息的配置,当事件并发发生时,对数据初始化、数据运算就一定要注意互斥,所以要巧用锁,在设计时,根据对象的特性不同,分配不同的锁。 - 类内封装还是类外要斟酌。在io管理类基于epoll来对文件进行一个监控,在套接字进入io管理类并进行登记时,需要对套接字进行分装。分装时机应思考一下,是进入io管理类由io封装,还是以一个封装好的对象传入io类中。对于时机的把控,我认为要看这个封装对象的使用场景,是只有io使用(辅助io类功能的实现),还是说会被复用,如果会被复用,则应该要先进行封装,在传给其他类。 - 巧用多态性。在io类中,idle函数是继承schedule类的,idle函数会在调度器初始状态、无任务时启动一占有资源。但在io类类中并改写为一个循环,用于epoll监控。(我在重写时,单独开辟函数来监控事件并接收调度,但因父子类函数间调用是错误的行为而无法实现) - 静态对象利用。c++对于静态对象的初始化,在编译时就会为静态对象开辟内存,所有类都共享这一份静态资源,在整个服务器代码中,可以很常见静态对象,当我们需要利用一个对象的相关功能,可以从外部调用静态函数返回一个指向该对象的指针,这样做可以避免初始一个对象时带来不必要的开销(这种静态函数返回资源对象指针,我认为对资源管理类来说是很有用处的)。
    1.6、致谢
    - 感谢sylar开源代码供网友学习。
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值