大多数线程池实现都离不开锁的应用,如互斥量pthread_mutex*联合条件变量pthread_cond*。家喻户晓,锁的应用对于程序性能影响较大,尽管现有的pthread_mutex*在锁的申请与开释方面做了较大的优化,然而,线程池的实现是能够做到无锁化的。

1.常见线程池实现原理

如上图所示,工作队列由主线程和工作者线程共享,主线程将工作放进工作队列,工作者线程从工作队列中取出工作执行。共享工作队列的操作需在互斥量的爱护下平安进行,主线程将工作放进工作队列时若检测到以后待执行的工作数目小于工作者线程总数,则需应用条件变量唤醒可能处于期待状态的工作者线程。当然,还有其余中央可能也会应用到互斥量和条件变量,不再赘述。

2.无锁化线程池实现原理

为解决无锁化的问题,须要防止共享资源的竞争,因而将共享工作队列加以拆分成每工作线程一个工作队列的形式。对于主线程放入工作和工作线程取出工作的竞争问题,能够采取环形队列的形式防止。在解决了锁机制之后,就只剩下条件变量的问题了,条件变量自身即解决条件满足时的线程通信问题,而信号作为一种通信形式,能够代替之,其大体编程范式为:

sigemptyset (&oldmask);sigemptyset (&signal_mask);sigaddset (&signal_mask, SIGUSR1);rc = pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);if (rc != 0) { debug(TPOOL_ERROR, "SIG_BLOCK failed"); return -1;}...while (!condition) { rc = sigwait (&signal_mask, NULL); if (rc != 0) { debug(TPOOL_ERROR, "sigwait failed"); return -1; }}rc = pthread_sigmask(SIG_SETMASK, &oldmask, NULL);if (rc != 0) { debug(TPOOL_ERROR, "SIG_SETMASK failed"); return -1;}

须要C/C++ Linux服务器架构师学习材料加qun(563998835)(材料包含C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),收费分享

3.无锁化线程池具体实现

在无锁线程池中,区别于常见线程池的中央次要在于信号与条件变量、任务调度算法、减少或缩小线程数目后的工作迁徙,另外还有一点就是环形队列的实现参考了Linux内核中的kfifo实现。

(1) 信号与条件变量

信号与条件变量的区别次要在于条件变量的唤醒(signal)对于接管线程而言能够疏忽,而在未设置信号处理函数的状况下信号的接管会导致接管线程甚至整个程序的终止,因而须要在线程池产生线程之前指定信号处理函数,这样新生的线程会继承这个信号处理函数。多线程中信号的发送次要采纳pthread_kill,为防止应用其余信号,本程序中应用了SIGUSR1。

(2) 任务调度算法

常见线程池实现的任务调度次要在操作系统一级通过线程调度实现。思考到负载平衡,主线程放入工作时应采取适合的任务调度算法将工作放入对应的工作者线程队列,本程序目前已实现Round-Robin和Least-Load算法。Round-Robin即轮询式地调配工作,Least-Load即抉择以后具备起码工作的工作者线程放入。

(3) 工作迁徙

在线程的动静减少和缩小的过程中,同样基于负载平衡的考量,波及到现有工作的迁徙问题。负载平衡算法次要基于均匀工作量的思维,即统计以后时刻的总任务数目,均分至每一个线程,求出每个工作者线程应该减少或缩小的工作数目,而后从头至尾遍历,须要移出工作的线程与须要移入工作的线程执行工作迁徙,互相对消。最初若还有多进去的工作,再顺次调配。迁入工作不存在竞态,因为退出工作始终由主线程实现,而迁出工作则存在竞态,因为在迁出工作的同时工作者线程可能在同时执行工作。所以须要采纳原子操作加以修改,其次要思维即预取技术,大抵实现为:

do { work = NULL; if (thread_queue_len(thread) <= 0) //also atomic break; tmp = thread->out; //prefetch work work = &thread->work_queue[queue_offset(tmp)];} while (!__sync_bool_compare_and_swap(&thread->out, tmp, tmp + 1));if (work) { // do something在线程的动静缩小后,原先线程上未能执行完的工作只须要由 //主线程再次依据任务调度算法重新分配至其余存活的工作者线程队列中即可,不 //存在上述问题,当然,此时能够同时执行负载平衡算法加以优化。}

(4) 环形队列

源码中环形队列实现次要参考了linux内核中kfifo的实现,如下图所示:

队列长度为2的整次幂,out和in下标始终递增至越界后回转,其类型为unsigned int,即out指针始终追赶in指针,out和in映射至FiFo的对应下标处,其间的元素即为队列元素。

线程池 c linux 编程,关于c++:linux-c编程之高效线程池如何实现无琐化相关推荐

  1. linux进程池动态维护,可直接商用的跨平台c,c++动态线程池,任务池stpool库

    stpool是一个轻便高效的动态跨平台的线程池/任务池库. 常规线程池的缺点: 1. 总是启动时候就开启固定数目的线程,而不管系统的繁忙状态 (这是很浪费系统资源的). 2. 当任务繁重的时候,即使线 ...

  2. 【线程池】自行准备linux环境,带你手写线程池,只需仅仅150行代码|内存池|API|连接池|应用协议丨C/C++Linux服务器开发

    [线程池]自行准备linux环境,带你手写线程池,只需仅仅150行代码 视频讲解如下,点击观看: [线程池]自行准备linux环境,带你手写线程池,只需仅仅150行代码|内存池|API|连接池|应用协 ...

  3. Linux系统编程----12(线程概念,Linux线程实现原理,栈中ebp指针和ebp指针,线程的优缺点和共享资源)

    线程概念 什么是线程 在一个程序里的一个执行路线就叫做线程(thread). 更准确的定义是:线程是"一个进程内部的控制序列" 一切进程至少都有一个执行线程 线程在进程内部运行,本 ...

  4. 【Linux系统编程学习】Linux线程控制原语

    此为牛客Linux C++课程笔记. 0. 关于线程 注意:LWP号和线程id不同, LWP号是CPU分配时间片的依据,线程id是用于在进程内部区分线程的. 1. 线程与进程的区别 对于进程来说,相同 ...

  5. linux c 网络编程与信号量,linux网络编程-----线程同步--信号量

    开发使用多线程过程中, 不可避免的会出现多个线程同时操作同一块共享资源, 当操作全部为读时, 不会出现未知结果, 一旦当某个线程操作中有写操作时, 就会出现数据不同步的事件. 而出现数据混乱的原因:资 ...

  6. 【4万字Linux线程解析】从0开始学习Linux线程

    文章目录 一.线程基本概念 1. 并发和并行 2. 线程的引入 3. 什么是线程 4. Linux下的线程 5. 线程的优点和缺点 (1)计算密集型应用 (2)IO密集型应用 (3)计算密集型程序创建 ...

  7. 林世霖. linux环境编程图文指南,linux环境编程图文指南

    linux环境编程图文指南是一本linux编程环境配置指南,由林世霖.钟锦辉和李建辉三人共同编著.本书定位Linux环境编程入门与提高,全书拥有近400余幅案例图表,200多篇源代码,作者很多编程初入 ...

  8. linux无锁化编程--__sync_fetch_and_add系列原子操作函数

    linux支持的哪些操作是具有原子特性的?知道这些东西是理解和设计无锁化编程算法的基础. 下面的东西整理自网络.先感谢大家的分享! __sync_fetch_and_add系列的命令,发现这个系列命令 ...

  9. linux shell命令行及脚本编程实例详解_Linux高手必看的10本经典书籍

    Linux高手必看的10本经典书籍 Linux 是一个开放.灵活.跨平台的操作系统,上至庞大的数据中心,下至可放于掌心中的嵌入式设备,Linux 的身影无处不在. 如果你想成为一名精通 Linux 程 ...

最新文章

  1. 连接没反应_显示器USB接口的作用是什么?为什么会没有反应?
  2. 如何编写服务器文档记录
  3. San CLI 4.0 升级指南
  4. python设计模式21-策略模式
  5. matlab2c使用c++实现matlab函数系列教程-normstat函数
  6. word自带公式编辑_如何在word自带的公式编辑器中设置字体格式
  7. STK之Commu模块之二-仿真同步卫星与地面站通信显示EIRP分布
  8. CCNA考试题库中英文翻译版及答案10
  9. 基努·里维斯继续出演《黑客帝国4》|| 程序员吐槽大会精选片段
  10. XP系统常用的登录密码方法破解(一共9种)
  11. 现有大语言模型(ChatGPT)的上下文理解能力还是假象吗?
  12. 4x root 红米_红米Note 4X root教程_红米Note4X获取root权限的方法
  13. 自定义复选框checkbox样式
  14. 超级账本Fabric学习(二)Fabric1.0.0网络搭建(中)无业务逻辑处理的Fabric网络
  15. 为什么建议大家使用 Linux 开发?爽(外加七个感叹号)
  16. 【前端开发基础】CSS基础知识以及CSS3
  17. 下一个十年,区块链将如何厚“基”薄发?
  18. 用导函数的图像判断原函数的单调性
  19. 前端HTML弹窗的实现
  20. 键盘输入一段英文,输出其中的单词个数。

热门文章

  1. 错误处理:RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be
  2. 文巾解题 596. 超过5名学生的课
  3. Linux du命令和df命令区别
  4. 增强学习(Reinforcement Learning and Control)
  5. MATLAB与图像处理(四):将图片序列转化为视频文件,将视频文件转化为图片
  6. Project interpreter not specified(eclipse+pydev)
  7. python能解密java的_实现Java加密,Python解密的RSA非对称加密算法功能
  8. LeetCode题组:第206题-反转链表
  9. LeetCode-字符串-58. 最后一个单词的长度
  10. 20个非常有用的Java程序片段--转