ceph 线程池分析

news2025/1/16 7:00:38

ceph 线程池

1. WHY

  线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。 

2. WHAT

​ 线程池和工做队列实际上是密不可分的。让任务推入工做队列,而线程池中的线程负责从工做队列中取出任务进行处理。

	工做队列和线程池的关系,相似于狡兔和走狗的关系,正是由于有任务,因此才须要雇佣线程来完成任务,没有了狡兔,走狗也就失去了存在的意义。而线程必需要能够从工做队列中认领任务并完成,这就相似于猎狗要有追捕狡兔的功能 

3. HOW

​ 以osd侧的osd_op_tp线程为例:
对应于下面的代码分析流程
在这里插入图片描述

//线程池start在osd.init()
int OSD::init()
{
	osd_op_tp.start();
}

void ShardedThreadPool::start()
{
  shardedpool_lock.Lock();
  start_threads();
  shardedpool_lock.Unlock();
}


void ShardedThreadPool::start_threads()
{
  assert(shardedpool_lock.is_locked());
  int32_t thread_index = 0;
  while (threads_shardedpool.size() < num_threads) 
  {
    WorkThreadSharded *wt = new WorkThreadSharded(this, thread_index);
    threads_shardedpool.push_back(wt);//池子加入线程
    wt->create(thread_name.c_str());//创建线程
    thread_index++;
  }
}

void Thread::create(const char *name, size_t stacksize)
{
  assert(strlen(name) < 16);
  thread_name = name;

  int ret = try_create(stacksize);
}

int Thread::try_create(size_t stacksize)
{
  r = pthread_create(&thread_id, thread_attr, _entry_func, (void*)this);
  restore_sigset(&old_sigset);

  return r;
}

void *Thread::_entry_func(void *arg) 
{
  void *r = ((Thread*)arg)->entry_wrapper();
  return r;
}

void *Thread::entry_wrapper()
{
  ....
  return entry();
}

 struct WorkThreadSharded : public Thread 
 {
    ShardedThreadPool *pool;
    void *entry() override 
    {
      pool->shardedthreadpool_worker(thread_index);
      return 0;
    }
  }

void ShardedThreadPool::shardedthreadpool_worker(uint32_t thread_index)
{
    //轮询
  ldout(cct,10) << "worker start" << dendl;
   //队列初始化的时候便就入队了,详见各队列的构造函数
   wq->_process(thread_index, hb);
  ldout(cct,10) << "sharded worker finish" << dendl;

  cct->get_heartbeat_map()->remove_worker(hb);
}

//ThreadPool实现的线程池,其每个线程都有机会处理工作队列的任意一个任务。
//这就会导致一个问题,如果任务之间有互斥性,那么正在处理该任务的两个线程有一个必须等待另一个处理完成后才能处理,从而导致线程的阻塞,性能下降
void OSD::ShardedOpWQ::_process(uint32_t thread_index, heartbeat_handle_d *hb)
{
    //任务调度方式做了改进
    osd->service.update_sched_out_queue();

    osd->callback_trigger();//precheck_finisher.queue(c); //async process//也会被ms_fast_dispatch调用 
    
  	lgeneric_subdout(osd->cct, osd, 4) << "dequeue status: ";//被阻塞的线程

	boost::optional<PGQueueable> qi;
    ThreadPool::TPHandle tp_handle(osd->cct, hb, timeout_interval,suicide_interval);
    qi->run(osd, pg, tp_handle);//处理pg事件
}

//另外一种方式入队
ms_fast_dispatch--> enqueue_op --> op_shardedwq.queue(make_pair(pg, PGQueueable(op, epoch)))
--> _enqueue(item)-->enqueue_fetch_next -->queue.add_request(std::move(item), cl, qosparam, cost)
    
总结如何使用
1.声明线程池成员ThreadPool *_tp

2.声明队列类型ThreadPool::WorkQueue_*_wq

3.重写WorkQueue中对应函数_void_process,_void_process_finish

4.调用*_tp.add_work_queue(*_wq)将队列传入

4. 线程池及线程分类

  1. 第一类是普通类线程:

使用此类线程类直接申明继承自Thread,重写一个entry函数,在进程启动最初时,调用了create函数创建了线程,同时使用它的人必须自己定义消息队列。上面大部分线程都是此类,比如FileJournal::write_thread就是一个FileJournal::Writer类对象,它自己定义了消息队列FileJournal::writeq

第二类是SafeTimerThread类线程:

此类线程使用者可以直接申明一个SafeTimer成员变量,因为SafeTimer中已经封装了SafeTimerThread类和一个消息队列(成员是Context回调类),并完成了entry函数的逻辑流程。使用者使用方法,就是设置回调函数,通过SafeTimer::add_event_after函数将钩子埋入,等待规定时间到达后执行。

第三类是FinisherThread类线程:

此类线程使用者可以直接申明一个Finisher成员变量,因为Finsher中已经封装了FinisherThread类和一个消息队列(成员是Context回调类),并完成entry函数的逻辑流程。使用者使用方法,就是设置回调函数,通过Finisher::queue函数将钩子埋入,等待某类操作完成后执行。处理回调complete函数

第四类是ThreadPool内部线程:

这类线程由于是具体工作类线程,所以他们一般都是以线程池形式一下创建多个。ThreadPool类内部有多个线程set<WorkThread*>和多个消息队列vector<WorkQueue_*>组成。工作流程就是线程不断的轮询从队列中拿去数据进行操作(如下图)

  1. op_tp 处理client来的请求

    disk_tp 处理scrub操作

    recovery_tp处理recovery_tp操作

    command_tp 处理命令行来的操作

    FileStore::op_tp 处理底层数据操作

进行操作(如下图)

  1. op_tp 处理client来的请求

    disk_tp 处理scrub操作

    recovery_tp处理recovery_tp操作

    command_tp 处理命令行来的操作

    FileStore::op_tp 处理底层数据操作

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

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

相关文章

从ChargePoint到能链智电,充电服务商的价值创新

近日&#xff0c;吉林长春出租车雨雪之中排队换电艰难的视频引起热议。 新能源汽车充换电困难&#xff0c;一方面说明电池在寒冷天气下的性能有优化空间&#xff0c;另一方面也反映出国内新能源汽车配套基础设施仍然存在较大需求缺口。 充电基础设施建设对新能源汽车推广意义…

LabView 总结 持续追加

波形图和波形图表 波形图是同时将所有要显示的点显示出来&#xff0c;接收的数据是数组&#xff0c;当然要显示多条曲线&#xff0c; 波形图表在具有波形图的功能上还有逐点显示&#xff0c;接收数据是一个数值 条件结构 可以用于枚举、字符串、数值 当需要连接两个端点时&a…

[附源码]计算机毕业设计springboot二手书店设计论文

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 Ma…

聚苏丹红Ⅲ膜/磺化聚醚醚酮膜/ SiO2/Ag纤维复合材料修饰多巴胺的研究

小编在这里给大家整理了聚苏丹红Ⅲ膜/磺化聚醚醚酮膜/ SiO2/Ag纤维复合材料修饰多巴胺的研究&#xff0c;一起来看看吧&#xff01; 聚苏丹红Ⅲ膜修饰多巴胺的研究&#xff1a; 目的建立测定盐酸多巴胺注射液 含量的电化学分析新方法.方法采用循环伏安法研究盐酸多巴胺在膜修饰…

面试汇总-MySQL-杂项

目录 1、悲观锁和乐观锁 2、数据库关键字的执行顺序是什么&#xff1f; 3、SQL优化 3.1、如何进行sql优化&#xff1f; 3.2、常见的join算法 3.2.1、Hash Join 3.2.2、Merge Join 3.2.3、Nested Loop Join 3.3、Join前后表的数据量对查询性能有什么影响&#xff1f; …

云原生架构实践前言

开场白 每个开发人员都可以拥有自己私有的 DEV 环境&#xff0c;方便在业余时间进行探索尝试&#xff0c;学习新的技术&#xff0c;拓宽知识面&#xff0c;保持技术敏感性&#xff0c;不至于被日新月异的快速变革所匆匆淘汰。 自身实力过硬&#xff0c;即使身处激烈的竞争环境&…

猿如意开发工具|python3.10

目录 写在前面 正文 官网 python3.10 下载 总结 写在前面 因为我的电脑系统是32位的&#xff0c;而猿如意要64位&#xff0c;所以&#xff0c;我没法下载&#xff0c;在此&#xff0c;我就只好评论一下python3.10这个软件和猿如意官网。 正文 官网 首先&#xff0c;…

使用Nacos作为配置中心

目录 一&#xff0c;配置中心简介 Nacos Config入门 二&#xff0c;nacos差异化配置 三&#xff0c;nacos共享配置 同一个微服务的不同环境之间共享配置 不同微服务中间共享配置 四&#xff0c;nacos的命名空间&组 nacos的几个概念 创建命名空间(Namespace) 组 一…

压测工具nGrinder:性能测试入门

1 前言 nGrinder将Grinder的控制台和代理包装起来&#xff0c;并扩展了支持多个并发测试的特性。用户可以设置使用多个进程或线程来并发的执行该脚本&#xff0c;通过不断重复地执行测试脚本&#xff0c;来模拟多并发用户访问。 2 相应参数配置 (1)输入需要测试的url地址&…

STM32实战总结:HAL之看门狗

在由单片机构成的微型计算机系统中&#xff0c;单片机的工作常常会受到来自外界电磁场的干扰&#xff0c;造成程序的跑飞&#xff0c;而陷入死循环&#xff1b;或者因为用户配置代码出现BUG&#xff0c;导致芯片无法正常工作。出于对单片机运行状态进行实时监测的考虑&#xff…

java面试强基(14)

Java 中 IO 流分为几种? 按照流的流向分&#xff0c;可以分为输入流和输出流&#xff1b;按照操作单元划分&#xff0c;可以划分为字节流和字符流&#xff1b;按照流的角色划分为节点流和处理流。 Java IO 流共涉及 40 多个类&#xff0c;这些类看上去很杂乱&#xff0c;但实…

[附源码]计算机毕业设计springboot病房管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

跨国并购数据库:SDC跨国数据库、Thomson数据库、A股上市公司并购数据库等多指标数据(4W+)

&#xff08;1&#xff09;SDC跨国数据库 1、数据来源&#xff1a;WRDS沃顿数据库Thomson Reuters SDC - Mergers and Acquisitions板块 2、时间跨度&#xff1a;1982年1月1日至2020年12月31日 3、区域范围&#xff1a;全国 4、指标说明&#xff1a; 数据的所有并购方都为…

DDD 与 EDA- 核心逻辑提炼方法论

在【DDD与应用架构】一文中我们说过&#xff0c;应用架构的存在就是为了把一团混沌的代码变得有秩序&#xff0c;好管理。我们保持最核心逻辑不变&#xff0c;就可以保持系统的稳定与发展。领域驱动设计的作者 Eric Evans 说&#xff1a;“为了使领域模型成为有价值的资产&…

华夏天信携手华为云开天aPaaS,打造安全、高效、节能的主煤流运输系统

摘要&#xff1a;基于开天aPaaS集成工作台&#xff0c;主煤流运输系统如何实现多源异构数据融合、皮带物料和人员违章的智能感知&#xff0c;以及皮带的智能控制。灵活架构、高效集成、快速开发&#xff01;本文分享自华为云社区《华夏天信携手华为云开天aPaaS&#xff0c;打造…

SSM三大框架之MyBatis总结【动力节点老杜】

文章目录JDBC的缺点MyBatis一、基础概念二、开发第一个mybatis程序1.resources目录&#xff1a;2.开发步骤3.从 XML 中构建 **SqlSessionFactory**4.mybatis中有两个主要的配置文件&#xff1a;5.关于第一个程序的小细节6.关于mybatis的事务管理机制。&#xff08;深度剖析&…

springboot+jsp高校学生宿舍管理系统-宿管带前端

本系统采用从上往下的步骤开发&#xff0c;基本功能如下&#xff1a; 本课题要求实现一套宿舍管理系统&#xff0c;系统主要包括个人中心、学生管理、宿管管理、报修信息管理、费用缴纳管理、留言板管理、论坛管理、系统管理等功能&#xff1b; 管理员用例图如下所示&#xff1…

抖音达人探店有用吗?算不算过时呢

其实我看到这个问题的时候也曾怀疑探店的方式真的对当下年轻人有作用吗&#xff1f;会不会有人怀疑探店达人和商家是串通好的&#xff1f;毕竟在有利益链的情况下&#xff0c;我们还能否相信仅仅靠一个视频就能知晓事物的孰好孰坏&#xff1f;今天就来为大家分析下抖音达人探店…

xss-labs/level7

我们如同一下构造那样 <script>alert(xss)</script> 产生以下回显 接着查看源代码 发现第一个输出点被转义了 没有利用价值了 第二个输出点则是可以发现script关键字直接给干没了 氧化钙!!! 似此 如何处之&#xff1f; 我们猜测后台服务器还是对一些特殊字符进…

软件测试全套教程,软件测试自学线路图

目录 一、背景&#xff1a; 二、行动&#xff1a; 三、软件测试实战具体路线&#xff1a; 第0阶段 &#xff1a;软件测试行业和个人匹配度分析 第1阶段&#xff1a;软件行业前景分析大纲解读 第2阶段&#xff1a;软件测试基础知识 第3阶段&#xff1a;需求分析阶段 第4…