Linux 线程池源码分析

Linux 线程池源码分析

**

线 程 池

一、介绍线程池的文件

thread_pool.c --> 线程池源码,用户不需要修改,如果要使用线程池接口,只需要把这个文件一起编译就行。
thread_pool.h --> 线程池中结构体,函数声明,宏定义…

二、线程池实现过程。

1、什么是线程池?
线程池就是多个线程组合在一起的集合,就像一家公司一样,由多个员工组成的一个集合,
当有任务时,这些线程就会去处理任务,当没有任务时,线程就会休息。
2、如何描述一个线程池? -> 使用一个结构体来描述。
typedef struct thread_pool
{
	pthread_mutex_t lock;          ---> 互斥锁
	pthread_cond_t  cond;          ---> 条件变量
	bool shutdown;                 ---> 线程池状态 true->关闭  false->开启
	struct task *task_list;        ---> 任务队列头节点
	pthread_t *tids;               ---> 存储线程池中所有线程ID号空间的地址
	unsigned max_waiting_tasks;    ---> 线程池中最大等待的任务个数
	unsigned waiting_tasks;        ---> 线程池正在等待的任务个数
	unsigned active_threads;       ---> 当前线程池线程的个数
}thread_pool;struct thread_pool取了一个新的别名叫thread_pool。
不取别名,声明结构体变量和指针:
struct thread_pool pool;
struct thread_pool *pool;

取了别名之后,声明:
thread_pool pool;
thread_pool *pool;

//任务链表结构体的原型
struct task
{
	void *(*do_task)(void *arg);   ---> 任务执行函数
	void *arg;                     ---> 参数
    struct task *next;             ---> 指针域,用于存放下一个任务的地址
};

三、线程池实现接口。

1、初始化线程池。
函数接口: bool init_pool(thread_pool *pool, unsigned int threads_number)c

    pool: 线程池结构体的地址
    threads_number: 初始化线程池条数。

返回值:
	成功:true
	失败:false

总结: 初始化线程池中一些变量以及申请空间、设置起始值。
2、投放任务到线程池中。
函数接口: bool add_task(thread_pool *pool,void *(*do_task)(void *arg), void *arg)

    pool:线程池结构体的地址	
    do_task: 新任务的执行函数
    arg: 传递给新任务执行函数的参数

返回值:
	成功:true
	失败:false

总结: 为新任务申请堆区空间,如果申请成功,就将该节点尾插到链表的末尾,
       添加成功后,就随机唤醒一个线程来做这个任务。
3、分析线程的例程函数。
	总结:如果线程池处于开启状态,并且没有任务做,那么线程就会睡眠,只要有任务做,
	     无论线程池是开启还是关闭,线程就会继续做任务,把头节点的下一个节点取出,
	     执行完任务函数之后,就继续下一个任务/睡眠。
4、添加线程。
函数接口: int add_thread(thread_pool *pool, unsigned additional_threads)

    pool: 线程池结构体的地址
    additional_threads: 添加线程的条数

返回值:
	成功:实际创建的条数
	失败:-1

总结: 往线程池中添加线程,如果大于20条,就会创建失败。
5、删除线程。
函数接口: int remove_thread(thread_pool *pool, unsigned int removing_threads)

    pool: 线程池结构体的地址
    removing_threads: 需要删除线程的条数

返回值:
	成功:当前剩余的条数
	失败:-1

总结: 删除0条,可以返回当前剩余的条数。
6、 销毁线程池。
函数接口: bool destroy_pool(thread_pool *pool)

	pool:线程池结构体的地址

返回值:
	成功:true
	失败:false

总结: 设置标志位为true,然后唤醒所有线程起来退出,然后释放全部堆区空间。
四、线程池使用
总结 :如果我们需要使用线程池,不需要修改源码,
只需要知道如何调用init_pool()add_task()add_threads()rmove_threads()
这些函数就足够,还有就是要自己写清楚任务函数是什么。

thread_pool.h

#ifndef _THREAD_POOL_H_
#define _THREAD_POOL_H_

#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

#include <errno.h>
#include <pthread.h>

#define MAX_WAITING_TASKS	1000
#define MAX_ACTIVE_THREADS	20

struct task
{
	void *(*do_task)(void *arg);
	void *arg;

	struct task *next;
};

typedef struct thread_pool
{
	pthread_mutex_t lock;
	pthread_cond_t  cond;
	bool shutdown;
	struct task *task_list;
	pthread_t *tids;
	unsigned max_waiting_tasks;
	unsigned waiting_tasks;
	unsigned active_threads;
}thread_pool;


bool init_pool(thread_pool *pool, unsigned int threads_number);
bool add_task(thread_pool *pool, void *(*do_task)(void *arg), void *task);
int  add_thread(thread_pool *pool, unsigned int additional_threads_number);
int  remove_thread(thread_pool *pool, unsigned int removing_threads_number);
bool destroy_pool(thread_pool *pool);

void *routine(void *arg);


#endif

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值