首页 > 其他分享 >ThreadLoop实践学习笔记

ThreadLoop实践学习笔记

时间:2024-07-02 23:53:09浏览次数:22  
标签:Task 实践 笔记 监听 ThreadLoop TaskLoop Timer Event

背景

在日常工作和学习源码过程中,经常可以看到ThreadLoop的运用,发现ThreadLoop作为一个基础工具,在具体项目中有不同而又十分相似的实现,虽然核心的机制万变不离其宗(IO多路复用),但面向的业务场景不同导致了不同的实践结果,目前见过有几种ThreadLoop的实践,本文做一个分析记录和知识点的总结

基础TaskLoop:

面向Task:

Task类型包裹回调函数和必要数据,如have_run,is_run,task_tag等,TaskLoop负责执行Task,实质是处理Task类型包裹的回调函数

  • 核心接口:PostTask(Task)、PostDelayTask(Task)、PostRepeatTask(Task)
  • 功能:用户将Task交给线程进行异步处理,同时实现简单的Timer机制,对任务触发的时间进行延迟或重复
  • 面向场景:工作线程执行Task
  • 缺点:仅能对Task进行处理,无法充分使用多路复用机制监听Socket或其他fd
  • 代码:TaskLoop-Task

面向Event:

Event类型和Task相比,拥有了事件的语义,Event事件=需要监听的触发源+事件处理回调,一般来说触发源设计为Event Fd可以完美适配IO多路复用机制,同时仅监听Event fd可以给上层组件足够的灵活性,可以认为这是面向事件ThreadLoop很优雅的设计方法了

  • 核心接口:在面向Task的基础上,增加对事件的监听AddWatch(Event)
  • 功能:提供文件描述符监听的功能
  • 面向场景:事件驱动,需要监听文件描述符,例如Socket、Timer,上层仅需设计自己需要的Event即可实现定制化需求,例如进阶TaskLoop中的Timer就是很好的例子
  • 具体实践:
    epoll+Event,基于epoll_data.ptr的指针完成监听事件的处理,在Event中设定各类事件(或指定事件)的回调,muduo的channel就是基于这种机制设计的
  • 代码:TaskLoop-Event
注意:  
    Event类可以设计为基类,事件处理回调OnEventCallback可以通过识别Event的不同类型做事件的分发,完成Event内信息的传递,后续也可以通过基类->子类的转换,实现更多的任务处理和信息传递能力

讨论1:
    除了poll多路复用+wakeupFd可以用于实现任务/事件队列,相似的也可以使用条件变量的方式做事件的同步,但条件变量有唤醒丢失和虚假唤醒等问题
    相较而言FD的多路复用监听机制更加稳定,同时基于文件描述符监听的方式,可以增加基于Timer FD的功能

讨论2:
    在具体的实践中,只要能完成实际的业务需求也可以不用解耦,可直接将业务逻辑回调写到secket fd触发后的逻辑中,设计Event来提供监听的统一接口是为了通用性,提供可复用接口给其他模块

进阶TaskLoop

MsgQueue:TaskLoop+queue

基于TaskLoop,增加队列queue可实现一个异步的消息队列,提供PostMsg(msg)接口,MsgQueue初始化时绑定消息处理函数init(callback),

  • 核心原理:MsgQueue内部有一个事件触发的Event,绑定到TaskLoop中进行监听,当用户调用PostMsg(msg)向内部的queue压入消息时,主动唤醒Event FD来wakeup TaskLoop监听中的文件描述符,在Event唤醒的回调内取出queue积压的msg,调用提前绑定好的callback,完成消息的异步处理
  • 核心接口:PostMsg(msg)
  • 面向场景:异步消息处理队列
  • 代码:MsgQueue

Timer:TaskLoop+Timer Fd

基于面向Event的TaskLoop,在Timer的场景下,AddWatch(Event)实质上是AddWatch(TimerEventFd),因此只需要在AddWatch(Event)的基础上做TimerFd创建的封装即可

  • 核心接口:AddTimer(Task)
  • 面向场景:定时器任务处理
  • 代码:TimerMng

ThreadLoopMng

线程池,维护多个ThreadLoop的生命周期,派发任务

  • 核心接口:TaskLoop* GetTaskLoop();
  • 面向场景:线程池管理工作线程,维护线程生命周期

标签:Task,实践,笔记,监听,ThreadLoop,TaskLoop,Timer,Event
From: https://www.cnblogs.com/AndGate/p/18280754

相关文章

  • Linux源码阅读笔记08-进程调度API系统调用案例分析
    kthread_create_on_nodekthread_create_on_node函数功能:指定存储节点创建新内核线程。源码如下:操作实战#include<linux/module.h>#include<linux/pid.h>#include<linux/sched.h>#include<linux/kthread.h>#include<linux/wait.h>intMyThreadFunc(void*......
  • 维克日记 v0.4.2:开发者友好的数字化笔记工具
     维克日记,专为技术开发者和笔记爱好者设计的数字化笔记工具,以其强大的功能和灵活的配置赢得了用户的好评。软件采用Markdown语法,提供实时预览功能,让您的笔记编辑更加高效和直观。维克日记的用户界面简洁而功能齐全,无需复杂的设置,即可开始记录您的思路和创意。它支持表格可视化......
  • 江协科技51单片机-学习笔记(1)-课程简介
    1、声明本人最近在学习b站up主“江协科技”制件的“51单片机入门教程”,为了便于自己以后复习51单片机的相关知识,遂将自己学习过程中认为重要的知识点进行了笔记记录。本人将学习笔记发布在CSDN上,目的是方便小伙伴们一起学习和交流单片机相关知识,共同进步。本人所写的笔记和up......
  • DApp设计与开发 课程笔记(六):NFT交易市场后端开发
    笔记对应课程内容为成都信息工程大学区块链产业学院老师梁培利的DApp设计与开发17-18课笔记中提到的名词不做过多解释不懂就搜!tokenuri对应一个metadata的json数据上传一个图片,将图片上传到IPFS,获得一个cid,然后将json格式的metadata上传到IPFS,然后给用户发送一个NFT......
  • 大模型技术方向:基于星火大模型的群聊对话分角色要素提取挑战赛笔记
    AI夏令营#Datawhale#夏令营基于星火大模型的群聊对话分角色要素提取挑战赛举办方:科大讯飞股份有限公司一、赛事背景在当今数字化时代,企业积累了丰富的对话数据,这些数据不仅是客户与企业之间交流的记录,更是隐藏着宝贵信息的宝库。在这个背景下,群聊对话分角色要素提取成为了企......
  • Python学习笔记
    数据类型和变量字面量:在代码中,被写下来的固定的值。常见有6中,数字、字符串、列表、元组、集合、字典字符串:由任意数量的字符如中文、英文、各类符合、数字等组成。如“你好”,“hello”,在Python中被双引号引起来的就是字符串。注释:在程序代码中对程序代码进行解释说明的文字。......
  • 【Java学习笔记】方法的使用
    【Java学习笔记】方法的使用一、一个例子二、方法的概念及使用(一)什么是方法(二)方法的定义(三)方法调用的执行过程(四)实参和形参的关系(重要)(五)没有返回值的方法三、方法重载(一)为什么需要方法重载(二)方法重载概念(三)方法签名四、递归(一)生活中的故事(二)递归的概念(三)递归执行过程分......
  • 【esp32 学习笔记】将lvgl融入esp-idf项目中
    lvgl科普lvgl 主要特点:Github库整体了解版本号编排原则屏幕兼容性LVGL 问题处理: lvgl与 FreeRTOS由于esp-idf本身带了FreeRTOS系统,因此需要关注一下操作系统相关的内容:voidlvgl_thread(void){while(1){uint32_ttime_till_next;......
  • Java学习笔记
      Linux系统-部署-运维系列导航  maven多环境配置,根据激活环境,只打包对应的配置文件1.多环境配置<profiles><profile><id>dev</id><properties><!--环境标识,需要与配置文件的名称相对应--><......
  • Perl 学习笔记
    Perl是一种高效、功能强大且灵活的编程语言,广泛用于文本处理、系统管理、网络编程、Web开发等领域。它由LarryWall在1987年首次发布,名字来源于“PracticalExtractionandReportLanguage”。Perl的特点强大的文本处理能力:Perl有着强大的正则表达式和字符串处理功能,......