热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python3线程池源码解析_源码解读TDengine中线程池的实现

这篇文章中提到了tsched的源码可以一读,所以去阅读了一下,总共220来行。1.阅读前工作通过上文了解到这段程序实现的是一个任务队列,同

这篇文章中提到了 tsched 的源码可以一读,所以去阅读了一下,总共220来行。

1. 阅读前工作

通过上文了解到这段程序实现的是一个任务队列,同时带有线程池。这段程序是计算机操作系统里经典的consumer-producer (生产者-消费者)问题的实现。凡是学过操作系统这门课的,都应该知道这个问题,做过习题。在阅读源码之前可以先尝试用伪代码实现上述生产者-消费者问题。

2. 如何阅读?

了解清楚使用场景

这是一个线程池,客户端可以提交任务,线程池按照顺序调度执行任务。通过阅读 tsched.h 头文件,知道主要有三个函数:

初始化命名的调度器、线程池:taosInitScheduler

生产者提交某个任务:taosScheduleTask

程序结束时的清理工作:taosCleanUpScheduler

通过搜索上述三个函数的调用, 知道初始化了两个调度器,有三个地方会提交任务。

两个线程池

定时器里的 tmr 线程池 : 队列长度一万,只有一个线程服务。此线程会执行到期的 timer 的回调函数。

tsc 线程池:队列长度一万,线程数量为所在机器 CPU 核心数的一半。这些线程负责:异步操作如执行语句,固定大小滑动窗口流式数据处理

两个生产者

上面提到了,有三个生产者会提交任务给线程池:

timer

stream

了解了清楚使用方、使用场景后,就容易读懂逻辑了。这里是一个标准的操作系统中生产者消费者的问题,用的也是标准解法:使用一个互斥量,两个信号量。线程池使用 pthread 来创建。

关键的数据结构

SSchedQueue 里面就是上述问题中的核心数据结构,除了放置上述提到的互斥量,信号量,还需要一个队列来存储要具体执行的任务。

SSchedMsg 结构来表示线程池任务,包含要执行的具体函数及所需参数。

源码里注释并不多,只能通过看具体实现来了解上述支持的执行模式。看到支持两种模式:执行fp,或者执行 tfp(ahandle, thandle)。

核心调度逻辑

上面提到了生产者,一直没有提到消费者。接着读 sched.c 里的源码,可以看到消费者就是线程池里每个线程的主框架逻辑: taosProcessSchedQueue。平常这些线程处于阻塞状态,等待任务。一旦生产者提交任务后,就会通知到消费者。消费者拿到提交的任务及参数,去执行。执行完之后继续进入上述阻塞的状态,这样周而复始。

这里有个疑问,消费者和生产者之间是异步的。消费完之后,总得有办法通知消费者,这一步在哪里做呢?读到这里可以花点时间翻翻源码,找找答案。

其实秘密也藏在当时提交任务的数据结构里。TDengine 里有样例代码,翻了翻,找到了这个 async demo。可以看到 taos_query_a 就是一个异步的query函数,里面带了 query语句异步执行完成后的回调函数:taos_insert_call_back)。

3. 一些思考

看的时候内心不断在思考、对比,比如优势、劣势是什么?我会怎么实现

优势

为何使用线程池?

通过固定线程池大小来固定资源开销,而且是程序初始化时申请资源,这在嵌入式设备里是非常重要的,如果资源不够用,那就快速失败,在程序一开始启动时就报错。

复用了线程,因为创建、销毁线程都是有开销的。这样在频繁创建、销毁线程情况下,可以节省开销,复用之前的线程。

任务和线程解耦:需要使用多线程的地方,只管提交任务就好了。线程的初始化、运行、状态切换由线程池来负责。

劣势

操作异步化,对程序员的心智要求更高。需要使用回调函数,需要存储上下文。但是在上述场景里还好, 都是一些固定的逻辑。

调试较麻烦,不是直来直去的逻辑。需要通过分析上下文及回调函数里的日志来分析问题。

有没有其他实现方式?

如果用 Go 语言实现,会很简单。使用 channel 来做任务分发,本身就是线程安全的。

使用 C 来写,个人觉得会限制 TDengine 的开源参与方。因为现在市场上会 C 的人比较少,而且主要集中在嵌入式领域。而且 C 的生态一般,语言的轮子比较少,所以很多工作都需要自己做,比如 http server,rpc 等。如果让我来设计实现 TDengine,我可能会优先考虑 Rust,既能精准控制内存,又有比较完善的社区,而且语言处于上升期,容易成为其中的明星项目,会有推广优势,比如能吸引一些本身对数据库不怎么关注,但是对 Rust 感兴趣的程序员。

4. 一个思考题

通过搜索 pthread_create 可以发现系统中还有其他创建线程的地方,并没有用到上述的线程池,比如 dnodeMWrite, TcpPool,cache,sync等。这些地方为什么没有使用线程池呢?

欢迎关注我的微信公众账号,会在第一时间更新,博客园上只有部分文章会发布



推荐阅读
  • 本文探讨了 Spring Boot 应用程序在不同配置下支持的最大并发连接数,重点分析了内置服务器(如 Tomcat、Jetty 和 Undertow)的默认设置及其对性能的影响。 ... [详细]
  • 最近团队在部署DLP,作为一个技术人员对于黑盒看不到的地方还是充满了好奇心。多次咨询乙方人员DLP的算法原理是什么,他们都以商业秘密为由避而不谈,不得已只能自己查资料学习,于是有了下面的浅见。身为甲方,虽然不需要开发DLP产品,但是也有必要弄明白DLP基本的原理。俗话说工欲善其事必先利其器,只有在懂这个工具的原理之后才能更加灵活地使用这个工具,即使出现意外情况也能快速排错,越接近底层,越接近真相。根据DLP的实际用途,本文将DLP检测分为2部分,泄露关键字检测和近似重复文档检测。 ... [详细]
  • 配置Windows操作系统以确保DAW(数字音频工作站)硬件和软件的高效运行可能是一个复杂且令人沮丧的过程。本文提供了一系列专业建议,帮助你优化Windows系统,确保录音和音频处理的流畅性。 ... [详细]
  • FinOps 与 Serverless 的结合:破解云成本难题
    本文探讨了如何通过 FinOps 实践优化 Serverless 应用的成本管理,提出了首个 Serverless 函数总成本估计模型,并分享了多种有效的成本优化策略。 ... [详细]
  • Valve 发布 Steam Deck 的新版 Windows 驱动程序
    Valve 最新发布了针对 Steam Deck 掌机的 Windows 驱动程序,旨在提升其在 Windows 环境下的兼容性、安全性和性能表现。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文介绍了如何在C#中启动一个应用程序,并通过枚举窗口来获取其主窗口句柄。当使用Process类启动程序时,我们通常只能获得进程的句柄,而主窗口句柄可能为0。因此,我们需要使用API函数和回调机制来准确获取主窗口句柄。 ... [详细]
  • Splay Tree 区间操作优化
    本文详细介绍了使用Splay Tree进行区间操作的实现方法,包括插入、删除、修改、翻转和求和等操作。通过这些操作,可以高效地处理动态序列问题,并且代码实现具有一定的挑战性,有助于编程能力的提升。 ... [详细]
  • Linux设备驱动程序:异步时间操作与调度机制
    本文介绍了Linux内核中的几种异步延迟操作方法,包括内核定时器、tasklet机制和工作队列。这些机制允许在未来的某个时间点执行任务,而无需阻塞当前线程,从而提高系统的响应性和效率。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • 本文深入探讨了 Python 中的循环结构(包括 for 循环和 while 循环)、函数定义与调用,以及面向对象编程的基础概念。通过详细解释和代码示例,帮助读者更好地理解和应用这些核心编程元素。 ... [详细]
  • 本文详细介绍了网络存储技术的基本概念、分类及应用场景。通过分析直连式存储(DAS)、网络附加存储(NAS)和存储区域网络(SAN)的特点,帮助读者理解不同存储方式的优势与局限性。 ... [详细]
  • 本文详细介绍了Python中列表的创建、访问、修改、排序及遍历等基本操作,帮助初学者快速掌握列表这一重要数据结构。 ... [详细]
  • 开源 高性能 云原生!时序数据库 TDengine 上线亚马逊Marketplace
    近日,涛思数据旗下开源、高性能、云原生的时序数据库(TimeSeriesDatabase,TSDB)TDengine 成功上线亚马逊云科技Marketplace,为用户提供了更加丰 ... [详细]
author-avatar
郝韵G
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有