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

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

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

思考

  • 线程池的作用?
  • 线程池的工作原理?
  • 线程池的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,以及对应的代码实现


相关文章
|
26天前
|
存储 NoSQL Redis
Redis 新版本引入多线程的利弊分析
【10月更文挑战第16天】Redis 新版本引入多线程是一个具有挑战性和机遇的改变。虽然多线程带来了一些潜在的问题和挑战,但也为 Redis 提供了进一步提升性能和扩展能力的可能性。在实际应用中,我们需要根据具体的需求和场景,综合评估多线程的利弊,谨慎地选择和使用 Redis 的新版本。同时,Redis 开发者也需要不断努力,优化和完善多线程机制,以提供更加稳定、高效和可靠的 Redis 服务。
30 1
|
1月前
线程CPU异常定位分析
【10月更文挑战第3天】 开发过程中会出现一些CPU异常升高的问题,想要定位到具体的位置就需要一系列的分析,记录一些分析手段。
61 0
|
5月前
|
存储 SQL 监控
JAVA 线程池的分析和使用
JAVA 线程池的分析和使用
40 0
|
6月前
|
SQL Dubbo Java
案例分析|线程池相关故障梳理&总结
本文作者梳理和分享了线程池类的故障,分别从故障视角和技术视角两个角度来分析总结,故障视角可以看到现象和教训,而技术视角可以透过现象看到本质更进一步可以看看如何避免。
84763 136
案例分析|线程池相关故障梳理&总结
|
2月前
|
并行计算 API 调度
探索Python中的并发编程:线程与进程的对比分析
【9月更文挑战第21天】本文深入探讨了Python中并发编程的核心概念,通过直观的代码示例和清晰的逻辑推理,引导读者理解线程与进程在解决并发问题时的不同应用场景。我们将从基础理论出发,逐步过渡到实际案例分析,旨在揭示Python并发模型的内在机制,并比较它们在执行效率、资源占用和适用场景方面的差异。文章不仅适合初学者构建并发编程的基础认识,同时也为有经验的开发者提供深度思考的视角。
|
3月前
|
存储 监控 Java
|
3月前
|
安全 Java 开发者
Swing 的线程安全分析
【8月更文挑战第22天】
59 4
|
3月前
|
Java 数据库连接 数据库
当线程中发生异常时的情况分析
【8月更文挑战第22天】
100 4
|
3月前
|
安全 Java 程序员
线程安全与 Vector 类的分析
【8月更文挑战第22天】
49 4
|
3月前
|
存储 缓存 安全
深度剖析Java HashMap:源码分析、线程安全与最佳实践
深度剖析Java HashMap:源码分析、线程安全与最佳实践