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

IO资源管理调度

  • 基于TCP/UDO实现服务器与客户端之间的连接,后台需要时刻接收来自客户端的连接信息,在高并发的环境,如何去实现对各个套接字的监控,sylar服务器使用的epoll方法,在网络套接字管理类,则是对epoll进行的一个封装。
  • soceket管理类基于epoll实现对网络连接的管理,整个类分为三部分,事件枚举,socket事件上下文类,IO管理函数。

“`c enum Event { // 无事件 NONE = 0x0, // 读事件(EPOLLIN) READ = 0x1, // 写事件(EPOLLOUT) WRITE = 0x4, }; “` – Event这里实现对对IO事件属性的设置,在套接字登记和消息返回时,evnent可以用来指明消息属性

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服务器底层是基于协程实现的调度器
 //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); 
 //epoll句柄 int m_epfd = 0; //原子量,用来记录其中的事件总数 std::atomic<size_t> m_pendingEventCount = {0}; /// IOManager的Mutex RWMutexType m_mutex; /// socket事件上下文的容器 std::vector<FdContext*> m_fdContexts; 

– 对于系统资源类型对象,应集中管理接受调度。在sylar服务器中,底层利用协程来运行函数的,同时在设计了一个调度器来登记每一个运行的函数,并进行相关调度。在进行设计时,对于复用资源性对象,进行封装处理,并设计一个管理类,来对是西安资源的调度 – 设计时,一定要注意并发的情况。在io管理类中,接收一个套接字,就需要做相关的信息的配置,当事件并发发生时,对数据初始化、数据运算就一定要注意互斥,所以要巧用锁,在设计时,根据对象的特性不同,分配不同的锁。 – 类内封装还是类外要斟酌。在io管理类基于epoll来对文件进行一个监控,在套接字进入io管理类并进行登记时,需要对套接字进行分装。分装时机应思考一下,是进入io管理类由io封装,还是以一个封装好的对象传入io类中。对于时机的把控,我认为要看这个封装对象的使用场景,是只有io使用(辅助io类功能的实现),还是说会被复用,如果会被复用,则应该要先进行封装,在传给其他类。 – 巧用多态性。在io类中,idle函数是继承schedule类的,idle函数会在调度器初始状态、无任务时启动一占有资源。但在io类类中并改写为一个循环,用于epoll监控。(我在重写时,单独开辟函数来监控事件并接收调度,但因父子类函数间调用是错误的行为而无法实现) – 静态对象利用。c++对于静态对象的初始化,在编译时就会为静态对象开辟内存,所有类都共享这一份静态资源,在整个服务器代码中,可以很常见静态对象,当我们需要利用一个对象的相关功能,可以从外部调用静态函数返回一个指向该对象的指针,这样做可以避免初始一个对象时带来不必要的开销(这种静态函数返回资源对象指针,我认为对资源管理类来说是很有用处的)。

– 感谢sylar开源代码供网友学习。

原文链接:https://www.cnblogs.com/wlm-198/p/12441229.html

原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/33618

(0)
优速盾-小U的头像优速盾-小U
上一篇 2025年4月24日 11:51
下一篇 2025年4月24日 23:41

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

优速盾注册领取大礼包www.cdnb.net
/sitemap.xml