Linux下线程池的理解与简单实现
首先,线程池是什么?顾名思义,就是把一堆开辟好的线程放在一个池子里统一管理,就是一个线程池。
其次,为什么要用线程池,难道来一个请求给它申请一个线程,请求处理完了释放线程不行么?也行,但是如果创建线程和销毁线程的时间比线程处理请求的时间长,而且请求很多的情况下,我们的CPU资源都浪费在了创建和销毁线程上了,所以这种方法的效率比较低,于是,我们可以将若干已经创建完成的线程放在一起统一管理,如果来了一个请求,我们从线程池中取出一个线程来处理,处理完了放回池内等待下一个任务,线程池的好处是避免了繁琐的创建和结束线程的时间,有效的利用了CPU资源。
按照我的理解,线程池的作用和双缓冲的作用类似,可以完成任务处理的“鱼贯”动作。
最后,如何才能创建一个线程池的模型呢,一般需要以下三个参与者:
1、线程池结构,它负责管理多个线程并提供任务队列的接口
2、工作线程,它们负责处理任务
3、任务队列,存放待处理的任务
有了三个参与者,下一个问题就是怎么使线程池安全有序的工作,可以使用POSIX中的信号量、互斥锁和条件变量等同步手段。有了这些认识,我们就可以创建自己的线程池模型,我在github上找了一个比较经典的线程池的例子,有兴趣的可以学习一下。
原作者github地址:https://github.com/Pithikos/C-Thread-Pool
线程池所需要的数据结构:
(1)、0/1信号量,用于当任务队列非空时通知线程,这里是用互斥锁和条件变量来实现的信号量,其实POSIX信号量的一种实现就是用的互斥锁和条件变量
/* Binary semaphore */
typedef struct bsem {
pthread_mutex_t mutex;
pthread_cond_t cond;
int v; //v的值非0即1
} bsem;
(2)、标识任务的结构体,prev指向的对象是当前任务的前一个任务,这里用pnext来标识更贴切
/* Job */
typedef struct job{
struct job* prev; /* pointer to previous job */
void* (*function)(void* arg); /* function pointer */
void* arg; /* function's argument */
} job;
(3)、工作队列
/* Job queue */
typedef struct jobqueue{
pthread_mutex_t rwmutex; /* used for queue r/w access */
job *front; /* pointer to front of queue */
job *rear; /* pointer to rear of queue */
bsem *has_jobs; /* flag as binary semaphore */
int len; /* number of jobs in queue */
} jobqueue;
互斥锁rwmutex用来同步对工作队列的读写操作,front用来标识工作队列中的第一个任务,rear用来标识工作队列中的最后一个任务,has_jobs用来提供对二值信号量的访问接口,len代表当前工作队列中的任务数量。
(4)、工作线程
/* Thread */
typedef struct thread{
int id; /* friendly id */
pthread_t pthread; /* pointer to actual thread */
struct thpool_* thpool_p; /* access to thpool */
} thread;
id标识第几个线程,pthread代表的是创建的真正的线程id,对于每个线程来说,都提供对所在线程池的访问
(5)、线程池结构
/* Threadpool */
typedef struct thpool_{
thread** threads; /* pointer to threads */
volatile int num_threads_alive; /* threads currently alive */
volatile int num_threads_working; /* threads currently working */
pthread_mutex_t thcount_lock; /* used for thread count etc */
jobqueue* jobqueue_p; /* pointer to the job queue */
} thpool_;
threads可以看做是一个指针数组,数组中的每个指针都指向一个线程结构,num_threads_alive标识的是线程池中有多少个可工作线程,num_threads_working代表的是当前线程池中正在工作的线程数目,互斥锁thcount_lock提供对线程池数据的互斥访问,同时,线程池需要和任务队列协作,所以还要提供对任务队列的访问。
线程池的工作流程:
初始化线程池、任务队列和工作线程->向任务队列中添加任务->将等候在条件变量(任务队列上有任务)上的一个线程唤醒并从该任务队列中取出第一个任务给该线程执行->等待任务队列中所有任务执行完毕->关闭线程池。
Linux下线程池的理解与简单实现的更多相关文章
- Linux 下线程的理解
2017-04-03 最近深入研究了下Linux线程的问题,发现自己之前一直有些许误解,特记之…… 关于Linux下的线程,各种介绍Linux的书籍都没有深入去解释的,或许真的如书上所述,Linux本 ...
- 【Java面试】简述一下你对线程池的理解?
到底是什么面试题, 让一个工作了4年的精神小伙,只是去参加了一场技术面试, 就被搞得精神萎靡.郁郁寡欢! 这一切的背后到底是道德的沦丧,还是人性的扭曲. 让我们一起揭秘一下这道面试题. 关于, &qu ...
- 在Linux下如何使用GCC编译程序、简单生成 静态库及动态库
最近在编写的一个Apache kafka 的C/C++客户端,,在看他写的 example中,他的编译是用librdkafka++.a和librdkafka.a 静态库编译的,,,而我们这 ...
- linux下线程
linux下线程 线程与进程的关系: 之前转载的微信文章,进程与线程的差别已经说得比較清楚了.能够查看之前转载的文章.linux进程与线程的差别. 创建一个线程: #include<pthrea ...
- Linux平台下线程池的原理及实现
转自:http://blog.csdn.net/lmh12506/article/details/7753952 前段时间在github上开了个库,准备实现自己的线程池的,因为换工作的事,一直也没有实 ...
- 线程和线程池的理解与java简单例子
1.线程 (1)理解,线程是系统分配处理器时间资源的基本单元也是系统调用的基本单位,简单理解就是一个或多个线程组成了一个进程,进程就像爸爸,线程就像儿子,有时候爸爸一个人干不了活就生了几个儿子干活,会 ...
- Linux线程池在server上简单应用
一.问题描写叙述 如今以C/S架构为例.client向server端发送要查找的数字,server端启动线程中的线程进行对应的查询.将查询结果显示出来. 二.实现方案 1. 整个project以cli ...
- 对于Android的线程和线程池的理解
Android的消息机制,主要是指Handler的运行机制,Handler的运行需要底层的MessageQueue 和 Looper的支撑,MessageQueue中文名消息队列,它的内部存储了一组消 ...
- linux C 线程池(物不可穷也~)
Linux 多线程编程之 线程池 的原理和一个简单的C实现,提高对多线程编 程的认知,同步处理等操作,以及如何在实际项目中高效的利用多线程开 发. 1. 线程池介绍 为什么需要线程池??? 目前的大 ...
随机推荐
- Requirejs2.0笔记
API http://requirejs.org/ RequireJS 插件 http://requirejs.org/docs/api.html#plugins ①require.js脚本的异步加载 ...
- 6天的巴厘岛旅行 I love Bali
6天的巴厘岛旅游今天结束了,从第一天的踏进异国之域的新奇,到最后一天的将且回程的恋恋不舍,要记下的.不愿忘记的东西太多太多. 1.下午5点半抵达巴厘岛登巴萨国际机场,7点半才出机场,让Ricky导游和 ...
- 烂泥:U盘安装Centos6.5
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 使用U盘安装Centos6.5,需要以下几个步骤: 1. 制作U盘linux系统 2. 设置服务器BIOS 3. 安装Centos,注意引导分区的安装 ...
- java加密算法--MD5加密和哈希散列带秘钥加密算法源码
package com.ompa.common.utils; import java.security.MessageDigest; import java.security.NoSuchAlgori ...
- Linux下Mysql安装
1.下载安装包 首先查看Linux版本: [root@localhost ~]# lsb_release -a LSB Version: :core-4.0-amd64:core-4.0-noarch ...
- BI Project Managerment
Design doc is the meta data of the code. The project management plan is crucial to your project sinc ...
- Hadoop 1.0 和 2.0 中的数据处理框架 - MapReduce
1. MapReduce - 映射.化简编程模型 1.1 MapReduce 的概念 1.1.1 map 和 reduce 1.1.2 shufftle 和 排序 MapReduce 保证每个 red ...
- CentOS 6.5部署安装Memcached
1. Yum安装Memcache 查找memcached yum search memcached 该命令可以查询yum库中有关memcached的安装包信息,以下是搜寻结果截图: 安装 memc ...
- ZooKeeper架构设计及其应用要点
问题导读: 1.ZooKeeper的数据模型是什么 ?2.ZooKeeper应用有哪些陷阱 ?3.每个节点(ZNode)中存储的是什么?4.一个ZNode维护了一个状态结构都包含了什么?5.ZNode ...
- HTML常用文本元素
HTML是超文本标记语言,它提供网页的具体内容,包括文本.表单.图像.表格.链接.多媒体.列表等.其中文本是我们遇到的最多的展示内容.正确的使用文本标签,会使页面具有语义化,也有利于SEO. 文本标签 ...