【p2p、分布式,区块链笔记 UPNP】: Libupnp的线程池简述

news2024/11/20 4:46:45
  • 线程池在网络编程中是一个关键的组成部分,尤其是处理高并发请求时,线程池可以显著提高系统的性能和资源利用效率。它的关键组成部分包括以下几个要素:
  • 任务队列:一个(或多个)用于存放待执行任务的队列。任务通常以函数指针或任务对象的形式存储在队列中。
  • 生产者: 负责生成任务并将任务提交到线程池的任务队列中。
  • 消费者: 从任务队列中获取任务并进行处理。

线程池结构

  • 线程池由各种任务队列、用到的锁和一些属性组成。
  • https://github1s.com/pupnp/pupnp/blob/branch-1.14.x/upnp/src/threadutil/ThreadPool.h
typedef struct THREADPOOL
{
       
    FreeList jobFreeList;                /*! 任务的空闲列表。 */
    LinkedList lowJobQ;                  /*! 低优先级任务队列。 */
    LinkedList medJobQ;                  /*! 中等优先级任务队列。 */
    LinkedList highJobQ;                 /*! 高优先级任务队列。 */
    ThreadPoolJob *persistentJob;        /*! 持久任务。 */

    ithread_mutex_t mutex;              /*! 保护任务队列的互斥锁。*/
    ithread_cond_t condition;           /*! 用于任务队列信号的条件变量。*/
    ithread_cond_t start_and_shutdown;  /*! 用于启动和关闭的条件变量。 */
    
    // 该变量只在 创建消费者线程CreateWorker 时使用,为1时阻塞其他线程,创建完成后通过start_and_shutdown通知其他继续运行
    int pendingWorkerThreadStart;       /*! 是否在等待新工作线程启动。 */
    
    int lastJobId;                      /*! 任务ID计数器。 */
    int shutdown;                       /*! 标识线程池是否正在关闭。 */
    int totalThreads;                   /*! 线程总数。 */
    int busyThreads;                    /*! 当前正在执行任务的线程数量。 */
    int persistentThreads;              /*! 持久线程的数量。 */
    ThreadPoolAttr attr;                /*! 线程池的属性。 */
    ThreadPoolStats stats;              /*! 统计数据。 */
} ThreadPool;

线程池的任务队列结构(以LINKEDLIST 为例)

  • LINKEDLIST :生产者和消费者共同操作的任务队列,线程池中一般存在多个生产者和多个消费者(共同push、pop),所以操作时要加锁。
  • 在LinkedList.h中也定义了链表的创建(ListInit)、插入(ListAddTail)和删除 (ListDelNode)函数。
  • 另外需要注意的是,当void *ListDelNode(LinkedList *list, ListNode *dnode, int freeItem)的freeItem == 0,则节点中的项会从链表中移除但不会被释放。其地址作为函数的返回值。
/*!
 * 如果 head->next = tail,那么链表为空。
 *
 * 要遍历链表,可以使用如下代码:
 *  LinkedList g;ListNode *temp = NULL;for (temp = ListHead(g); temp != NULL; temp = ListNext(g, temp)) {}
 */
typedef struct LINKEDLIST {
	ListNode head; // 链表的头节点,实际第一个数据节点存储在 head->next 中
	ListNode tail; // 链表的尾节点,实际最后一个数据节点存储在 tail->prev 中
	long size; // 链表的当前大小(节点个数)

	FreeList freeNodeList;  // 空闲节点列表,用于回收和重用内存
	free_function free_func; // 释放节点时使用的函数指针,ListInit时确定
	cmp_routine cmp_func; // 比较两个节点数据时使用的函数指针
} LinkedList;
  • ThreadPoolAdd函数调用ListAddTail将通过TPJobInit等函数创建并配置的ThreadPoolJob *对象加入到目标队列中。
  • 生产者的调用过程可见(【p2p、分布式,区块链笔记 UPNP】: Libupnp sample 02 tv_device)。其中的TimerThreadSchedule(&gTimerThread, timeTillRead, REL_SEC, &job, SHORT_TERM, id);通过ListAddBefore函数将job添加到gTimerThread,最终通过TimerThreadWorker调用ThreadPoolAdd添加任务队列。
    在这里插入图片描述
  • 消费者从队列中获取任务head = ListHead(&tp->lowJobQ);job = (ThreadPoolJob *)head->item;并删除节点ListDelNode(&tp->lowJobQ, head, 0);。然后通过job->func(job->arg);执行回调函数。消费者的调用过程见 【p2p、分布式,区块链笔记 UPNP】: Libupnp test_init.c 03 初始化SDK — 线程池初始化(UpnpInitThreadPools)的WorkerThread 。
ListNode
typedef struct LISTNODE {
    struct LISTNODE *prev;  // 指向前一个节点的指针
    struct LISTNODE *next;  // 指向下一个节点的指针
    void *item;             // 指向节点中存储的通用数据(任意类型的项,当前示例为指向ThreadPoolJob的指针)
} ListNode;
  • 下面的例子中highJobQ的head为ListNode类型,其中的item为ThreadPoolJob类型
// https://github1s.com/pupnp/pupnp/blob/branch-1.14.x/upnp/src/threadutil/ThreadPool.c#L547-L556
// 依次尝试从高、中、低优先级队列中取作业
				if (tp->highJobQ.size > 0) {
					head = ListHead(&tp->highJobQ);
					if (head == NULL) {
						tp->stats.workerThreads--;
						goto exit_function;
					}
					job = (ThreadPoolJob *)head->item;
					CalcWaitTime(tp, HIGH_PRIORITY, job);
					ListDelNode(&tp->highJobQ, head, 0);
ThreadPoolJob
/*! Internal ThreadPool Job. */
typedef struct THREADPOOLJOB
{
	start_routine func;
	void *arg;
	free_routine free_func;
	struct timeval requestTime;
	ThreadPriority priority;
	int jobId;
} ThreadPoolJob;

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2199849.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简单花20分钟学会top 命令手册 (linux上的任务管理器)

1. 介绍 top 是一个常用的 Linux 命令行工具,用于实时监视系统资源和进程的运行情况。用户可以通过 top 命令查看系统的 CPU 使用率、内存占用情况、进程列表等重要信息,帮助快速了解系统运行状态并进行性能监控。该工具可以认为相当于windows上的任务管…

什么是MAC地址?有必要隐藏MAC地址吗?

你是否曾经停下来思考,每当你上网时,你的数字足迹可能会泄露你的个人信息?可能你会问,MAC地址是什么?简单来说,每台联网的电脑MAC地址都是独一无二的,就像是你设备在网络世界中的身份证。它能帮…

MySQL多表查询案例

先看我的表数据 dept表 emp表 salgrade表 student表 course表 student_course表 1. 查询员工的姓名, 年龄, 职位, 部门信息(隐式内连接) -- 表:emp, dept -- 连接条件 emp.dept_id dept.id …

那些年,我们一起追过的函数:揭秘数学世界里的‘网红’们

在数学中,函数是一种特殊的关系,它将一个集合中的每个元素(称为自变量或输入)映射到另一个集合中的唯一元素(称为因变量或输出)。根据函数的性质和定义域、值域的不同,可以将函数分为多种类型。…

七氟烷麻醉药市场研究:未来几年年复合增长率CAGR为4.2%

七氟烷是一种吸入麻醉剂,用于在外科手术过程中诱导和维持全身麻醉。七氟烷是一种挥发性麻醉剂,常用于在外科手术过程中诱导和维持全身麻醉。它因起效快和作用消失快而受到青睐,是成人和儿科患者的理想选择。七氟烷通常通过吸入起作用&#xf…

如何使用Colly库进行大规模数据抓取?

在互联网时代,数据的价值日益凸显,大规模数据抓取成为获取信息的重要手段。Go语言因其高效的并发处理能力,成为编写大规模爬虫的首选语言。Colly库作为Go语言中一个轻量级且功能强大的爬虫框架,能够满足大规模数据抓取的需求。本文…

开源 Three.js 案例及入门教程分享

更多three.js学习资料分享https://www.wjx.cn/vm/OaQEBVS.aspx# 01.Three.js 雨和屋顶 在线预览: https://codepen.io/prisoner849/full/yLWMLjK 源码: https://codepen.io/prisoner849/pen/yLWMLjK 02.Three.js 有趣的 3D 航行 源码: …

【动态网站资源保存下载】

文章目录 概要解决思路技术细节小结 概要 我们在网上浏览网站时,经常有这样的需求:将浏览的网页保存下来,即使无网的情况下也可以继续浏览。比如一些教育类网站的PPT,内容为HTML格式的,无法作为PPT格式下载下来&#…

鸿蒙NEXT开始公测,哪些机型可以升级?鸿蒙版微信界面简洁

华为 Harmony OS NEXT 于10月8日正式开启公测,对鸿蒙 NEXT 系统感兴趣,想要第一时间尝鲜鸿蒙系统的话,千万不要错过本篇文章! 哪些手机可以参与鸿蒙 NEXT 公测? 首批参与鸿蒙 NEXT 公测的机型有华为 Mate 60 系列、华…

大型企业的云容器和javaee的关联技术

目前在企业中,尤其是大型互联网企业中,云容器越来越重要,原因是:云容器的架构能够提供一整套的,自动提交,自动打包,自动部署,自动重启,动态配置的解决方案 云容器的整体结…

21亿收官,2024年国庆档没有抱怨市场的资格

截至10月7日晚上8点,2024年国庆档票房已接近21亿大关,但成绩基本定格于此,较去年减少了7亿,回落至2018年水准。 在经历了暑假档票房较去年大幅下滑、中秋档票房回归至2014年水平后,国内电影市场对于国庆档表现出一种复…

【Fine-Tuning】大模型微调理论及方法, PytorchHuggingFace微调实战

Fine-Tuning: 大模型微调理论及方法, Pytorch&HuggingFace微调实战 文章目录 Fine-Tuning: 大模型微调理论及方法, Pytorch&HuggingFace微调实战1. 什么是微调(1) 为什么要进行微调(2) 经典简单例子:情感分析任务背景微调 (3) 为什么微调work, 理论解释下 2…

《2024世界机器人报告》:中国为全球最大市场

国际机器人联合会(IFR)在9月24日最新发布的《世界机器人报告》中表示,全球有约428万台机器人在工厂运行,同比增长10%。工业机器人年安装量连续第三年超过50万台,在2023年新部署的工业机器人中,有70%在亚洲&…

基于Springboot+Vue的物业智慧系统 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 在这个…

WordPress添加https协议致使后台打不开解决方法

由于删除WordPress缓存插件后操作不当,在加上升级处理,致使茹莱神兽博客的首页出现了https不兼容问题,WordPress后台也无法登陆,链接被误认为是定向重置次数过多,在网上找了好久的答案。 还有就是求助了好些人&#xf…

C++ —— 优先级队列(priority queue)的模拟实现

目录 杂谈 vector和list的区别 1. 优先级队列的定义 2. 优先级队列的模拟实现 3. 仿函数 链接: priority_queue - C Reference (cplusplus.com)https://legacy.cplusplus.com/reference/queue/priority_queue/?kwpriority_queue 杂谈 vector和list的区别 在…

Elastic Stack--16--ES三种分页策略

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 方式一:from size实现原理使用方式优缺点 方式二:scroll实现原理使用方式优缺点 方式三:search_after实现原理使用方式优缺点 三…

两个pdf怎么合并成一个pdf?超简单的合并方法分享

在日常工作和学习中,我们经常会遇到需要将多个PDF文件合并成一个文件的情况,以便更好地管理和分享。今天,将为大家详细介绍5种实用的方法,能够一键合并多个PDF文件,有需要的小伙伴快来一起学习下吧。 方法一&#xff1…

双十一买什么?双十一买什么东西最划算?超全双十一购物指南!

双十一即将到来,一年一度的购物狂欢盛宴再度开启!在海量的商品面前,怎样挑选出既心仪又实惠的好物,已然成为大家关注的重点。下面为您呈上一份极为全面的2024年双十一必买清单,助力您轻松购物,收获满满&…

详解Xilinx JESD204B PHY层端口信号含义及动态切换线速率(JESD204B五)

Xilinx官方提供了两个用于开发JESD204B的IP,其中一个完成PHY层设计,另一个完成传输层的逻辑,两个IP必须一起使用才能正常工作。 7系列FPGA只能使用最多12通道的JESD204B协议,线速率为1.0至12.5 Gb/s;而UltraScale和Ult…