线程池 - 分析与实现(一)

简介: 线程池 - 分析与实现(一)

线程池 - 分析与实现(一)

思考

  • 线程池的作用?
  • 线程池的工作原理?
  • 线程池的API有哪些?具体怎么理解?

充电站

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

线程池

作用

简述来讲,线程池的作用主要两个方面:

1)减少线程创建与销毁;

2) 异步解耦的作用。

稍微长篇的讲,其一就是对于线程的重用,线程的创建和销毁的开销是巨大的,而通过线程池的重用大大减少了这些不必要的开销,当然既然少了这么多消费内存的开销,则线程的执行速度起飞了。其二就是对于线程的管理,线程池可以提供定时、定期、单线程、并发数控制等功能。控制线程池的并发数可以有效的避免大量的线程池争夺CPU资源而造成堵塞。

举个小例子

着重强调异步解耦的作用,以写日志为例,如loginfo("------\n");,日志需要落盘,写入磁盘中。我们将日志“落盘”当成一个任务,把这个任务抛给线程池,对于应用程序而言,这样就可以大大提升“落盘”的效率。

“池子”中都些什么?

这里不得不有举个例子来说说了,把线程池看做银行营业厅,银行营业厅里有什么呢?有柜员、办业务的人、公示牌、等等。线程池类似这样的“银行营业厅”

1)柜员–>线程–>执行队列(很多的柜员);

2)办业务的人–>任务–>任务队列(很多办业务的人);

3)公式牌–>管理作用–>促使柜员与办业务的人有序进行。

这三项都具备各自的“属性”,后面代码中会介绍。

代码

代码实现

柜员–>线程–>执行队列

// 执行队列->双链表实现
typedef struct NWORKER {
  pthread_t thread; //线程ID,即工号
  int terminate;  //flag 终止标志
  struct NWORKQUEUE *workqueue; //线程池的对象
  struct NWORKER *prev;
  struct NWORKER *next;
} nWorker;

办业务的人–>任务–>任务队列

// 任务队列->双链表实现
typedef struct NJOB {
  void (*job_function)(struct NJOB *job); //回调函数
  void *user_data; //参数
  struct NJOB *prev;
  struct NJOB *next;
} nJob;

线程池核心管理任务队列和执行队列有秩序进行的组件,不要将线程池理解为了连接池。

// 线程池
typedef struct NTREADPOOL {
  struct NWORKER *workers; //多个柜员
  struct NJOB *waiting_jobs; //办业务的人
  pthread_mutex_t jobs_mtx; //公示牌->互斥锁
  pthread_cond_t jobs_cond; //公示牌->等待条件满足
} nWorkQueue;

用宏定义实现队列的添加和删除

// ADD:在list中添加item(头插法)
#define LL_ADD(item, list) do {   \
  item->prev = NULL;        \
  item->next = list;        \
  list = item;          \
} while(0)
// REMOVE:在list中删除item
#define LL_REMOVE(item, list) do {            \
  if (item->prev != NULL) item->prev->next = item->next;  \
  if (item->next != NULL) item->next->prev = item->prev;  \
  if (list == item) list = item->next;          \
  item->prev = item->next = NULL;             \
} while(0)

总结

    本文介绍了线程池用的作用,以形象的例子说明线程池的重要组成以及各个部分的代码实现。下篇将介绍线程池的API,以及对应的代码实现


相关文章
|
1月前
|
设计模式 消息中间件 安全
【JUC】(3)常见的设计模式概念分析与多把锁使用场景!!理解线程状态转换条件!带你深入JUC!!文章全程笔记干货!!
JUC专栏第三篇,带你继续深入JUC! 本篇文章涵盖内容:保护性暂停、生产者与消费者、Park&unPark、线程转换条件、多把锁情况分析、可重入锁、顺序控制 笔记共享!!文章全程干货!
122 1
|
2月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
|
存储 NoSQL Redis
Redis 新版本引入多线程的利弊分析
【10月更文挑战第16天】Redis 新版本引入多线程是一个具有挑战性和机遇的改变。虽然多线程带来了一些潜在的问题和挑战,但也为 Redis 提供了进一步提升性能和扩展能力的可能性。在实际应用中,我们需要根据具体的需求和场景,综合评估多线程的利弊,谨慎地选择和使用 Redis 的新版本。同时,Redis 开发者也需要不断努力,优化和完善多线程机制,以提供更加稳定、高效和可靠的 Redis 服务。
279 1
|
10月前
|
并行计算 安全 Java
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
693 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
线程CPU异常定位分析
【10月更文挑战第3天】 开发过程中会出现一些CPU异常升高的问题,想要定位到具体的位置就需要一系列的分析,记录一些分析手段。
277 0
|
11月前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
427 4
|
安全 Java API
Java线程池原理与锁机制分析
综上所述,Java线程池和锁机制是并发编程中极其重要的两个部分。线程池主要用于管理线程的生命周期和执行并发任务,而锁机制则用于保障线程安全和防止数据的并发错误。它们深入地结合在一起,成为Java高效并发编程实践中的关键要素。
180 0
|
存储 监控 Java
|
安全 Java 开发者
Swing 的线程安全分析
【8月更文挑战第22天】
265 4
|
Java 数据库连接 数据库
当线程中发生异常时的情况分析
【8月更文挑战第22天】
258 4

热门文章

最新文章