thread_pool.h
/*************************************************
*
* file name:thread_pool.h
* author :momolyl@126.com
* date :2024/06/10
* brief :线程池相关函数的头文件
* note :None
*
* CopyRight (c) 2024 momolyl@126.com All Right Reseverd
*
**************************************************/
#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 // 处于等待状态的线程数量最大为1000
#define MAX_ACTIVE_THREADS 20 // 活跃的线程数量
// 任务结点 单向链表的节点,类型
struct task
{
void *(*do_task)(void *arg); // 任务函数指针 指向线程要执行的任务 格式是固定的
void *arg; // 需要传递给任务的参数,如果不需要,则NULL
struct task *next; // 指向下一个任务结点的指针
};
// 线程池的管理结构体
typedef struct thread_pool
{
pthread_mutex_t lock; // 互斥锁
pthread_cond_t cond; // 条件量
bool shutdown; // 是否需要销毁线程池
struct task *task_list; // 用于存储任务的链表
pthread_t *tids; // 用于记录线程池中线程的ID
unsigned max_waiting_tasks; // 线程池中线程的数量最大值
unsigned waiting_tasks; // 处于等待状态的线程数量
unsigned active_threads; // 正在活跃的线程数量
} thread_pool;
/*************************************************
*
* func name :init_pool
* brief :初始化线程池
* func parameter:
* @pool:待初始化的线程池指针
* @threads_number:要创建的线程数量
* return :None
* note :None
* func author :momolyl@126.com
* date :2024/06/10
* version :V1.0
**************************************************/
// 初始化线程池
bool init_pool(thread_pool *pool, unsigned int threads_number);
/*************************************************
*
* func name :add_task
* brief :在线程池的任务链表中添加任务
* func parameter:
* @pool:线程池指针
* @do_task:任务函数指针
* @arg:任务函数的参数
* return :None
* note :None
* func author :momolyl@126.com
* date :2024/06/10
* version :V1.0
**************************************************/
// 向线程池中添加任务
bool add_task(thread_pool *pool, void *(*do_task)(void *arg), void *task);
/*************************************************
*
* func name :add_thread
* brief :向线程池加入新线程
* func parameter:
* @pool:线程池指针
* @additional_threads:要添加的线程数量
*
* return :None
* note :None
* func author :momolyl@126.com
* date :2024/06/10
* version :V1.0
**************************************************/
// 先线程池中添加线程
int add_thread(thread_pool *pool, unsigned int additional_threads_number);
/*************************************************
*
* func name :remove_thread
* brief :删除线程池中的线程数量
* func parameter:
* @pool:线程池指针
* @removing_threads:要删除的线程数量
*
* return :None
* note :None
* func author :momolyl@126.com
* date :2024/06/10
* version :V1.0
**************************************************/
// 从线程池中删除线程
int remove_thread(thread_pool *pool, unsigned int removing_threads_number);
/*************************************************
*
* func name :destroy_pool
* brief :销毁线程池
* func parameter:
* @pool:待销毁的线程池指针
*
* return :None
* note :None
* func author :momolyl@126.com
* date :2024/06/10
* version :V1.0
**************************************************/
// 销毁线程池
bool destroy_pool(thread_pool *pool);
/*************************************************
*
* func name :routine
* brief :线程要执行的任务函数
* func parameter:
* @arg:线程任务参数
*
* return :None
* note :None
* func author :momolyl@126.com
* date :2024/06/10
* version :V1.0
**************************************************/
// 任务函数
void *routine(void *arg);
#endif
thread_pool.c
#include "thread_pool.h"
void handler(void *arg)
{
printf("[%u] is ended.\n",
(unsigned)pthread_self());
pthread_mutex_unlock((pthread_mutex_t *)arg);
}
void *routine(void *arg)
{
#ifdef DEBUG
printf("[%u] is started.\n",
(unsigned)pthread_self());
#endif
thread_pool *pool = (thread_pool *)arg;
struct task *p;
while (1)
{
pthread_cleanup_push(handler, (void *)&pool->lock);
pthread_mutex_lock(&pool->lock);
while (pool->waiting_tasks == 0 && !pool->shutdown)
{
pthread_cond_wait(&pool->cond, &pool->lock);
}
if (pool->waiting_tasks == 0 && pool->shutdown == true)
{
pthread_mutex_unlock(&pool->lock);
pthread_exit(NULL);
}
p = pool->task_list->next;
pool->task_list->next = p->next;
pool->waiting_tasks--;
pthread_mutex_unlock(&pool->lock);
pthread_cleanup_pop(0);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
(p->do_task)(p->arg);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
free(p);
}
pthread_exit(NULL);
}
bool init_pool(thread_pool *pool, unsigned int threads_number)
{
pthread_mutex_init(&pool->lock, NULL);
pthread_cond_init(&pool->cond, NULL);
pool->shutdown = false;
pool->task_list = malloc(sizeof(struct task));
pool->tids = malloc(sizeof(pthread_t) * MAX_ACTIVE_THREADS);
if (pool->task_list == NULL || pool->tids == NULL)
{
perror("allocate memory error");
return false;
}
pool->task_list->next = NULL;
pool->max_waiting_tasks = MAX_WAITING_TASKS;
pool->waiting_tasks = 0;
pool->active_threads = threads_number;
int i;
for (i = 0; i < pool->active_threads; i++)
{
if (pthread_create(&((pool->tids)[i]), NULL,
routine, (void *)pool) != 0)
{
perror("create threads error");
return false;
}
#ifdef DEBUG
printf("[%u]:[%s] ==> tids[%d]: [%u] is created.\n",
(unsigned)pthread_self(), __FUNCTION__,
i, (unsigned)pool->tids[i]);
#endif
}
return true;
}
bool add_task(thread_pool *pool,
void *(*do_task)(void *arg), void *arg)
{
struct task *new_task = malloc(sizeof(struct task));
if (new_task == NULL)
{
perror("allocate memory error");
return false;
}
new_task->do_task = do_task;
new_task->arg = arg;
new_task->next = NULL;
pthread_mutex_lock(&pool->lock);
if (pool->waiting_tasks >= MAX_WAITING_TASKS)
{
pthread_mutex_unlock(&pool->lock);
fprintf(stderr, "too many tasks.\n");
free(new_task);
return false;
}
struct task *tmp = pool->task_list;
while (tmp->next != NULL)
tmp = tmp->next;
tmp->next = new_task;
pool->waiting_tasks++;
pthread_mutex_unlock(&pool->lock);
#ifdef DEBUG
printf("[%u][%s] ==> a new task has been added.\n",
(unsigned)pthread_self(), __FUNCTION__);
#endif
pthread_cond_signal(&pool->cond);
return true;
}
int add_thread(thread_pool *pool, unsigned additional_threads)
{
if (additional_threads == 0)
return 0;
unsigned total_threads =
pool->active_threads + additional_threads;
int i, actual_increment = 0;
for (i = pool->active_threads; i < total_threads && i < MAX_ACTIVE_THREADS; i++)
{
if (pthread_create(&((pool->tids)[i]),
NULL, routine, (void *)pool) != 0)
{
perror("add threads error");
if (actual_increment == 0)
return -1;
break;
}
actual_increment++;
#ifdef DEBUG
printf("[%u]:[%s] ==> tids[%d]: [%u] is created.\n",
(unsigned)pthread_self(), __FUNCTION__,
i, (unsigned)pool->tids[i]);
#endif
}
pool->active_threads += actual_increment;
return actual_increment;
}
int remove_thread(thread_pool *pool, unsigned int removing_threads)
{
if (removing_threads == 0)
return pool->active_threads;
int remaining_threads = pool->active_threads - removing_threads;
remaining_threads = remaining_threads > 0 ? remaining_threads : 1;
int i;
for (i = pool->active_threads - 1; i > remaining_threads - 1; i--)
{
errno = pthread_cancel(pool->tids[i]);
if (errno != 0)
break;
#ifdef DEBUG
printf("[%u]:[%s] ==> cancelling tids[%d]: [%u]...\n",
(unsigned)pthread_self(), __FUNCTION__,
i, (unsigned)pool->tids[i]);
#endif
}
if (i == pool->active_threads - 1)
return -1;
else
{
pool->active_threads = i + 1;
return i + 1;
}
}
bool destroy_pool(thread_pool *pool)
{
pool->shutdown = true;
pthread_cond_broadcast(&pool->cond);
int i;
for (i = 0; i < pool->active_threads; i++)
{
errno = pthread_join(pool->tids[i], NULL);
if (errno != 0)
{
printf("join tids[%d] error: %s\n",
i, strerror(errno));
}
else
printf("[%u] is joined\n", (unsigned)pool->tids[i]);
}
free(pool->task_list);
free(pool->tids);
free(pool);
return true;
}
main.c线程池函数使用示例
#include "thread_pool.h"
void *mytask(void *arg)
{
int n = (int)arg;
printf("[%u][%s] ==> job will be done in %d sec...\n",
(unsigned)pthread_self(), __FUNCTION__, n);
sleep(n);
printf("[%u][%s] ==> job done!\n",
(unsigned)pthread_self(), __FUNCTION__);
return NULL;
}
void *count_time(void *arg)
{
int i = 0;
while (1)
{
sleep(1);
printf("sec: %d\n", ++i);
}
}
int main(void)
{
pthread_t a;
pthread_create(&a, NULL, count_time, NULL);
thread_pool *pool = malloc(sizeof(thread_pool));
init_pool(pool, 2);
printf("throwing 3 tasks...\n");
add_task(pool, mytask, (void *)(rand() % 10));
add_task(pool, mytask, (void *)(rand() % 10));
add_task(pool, mytask, (void *)(rand() % 10));
printf("current thread number: %d\n",
remove_thread(pool, 0));
sleep(9);
printf("throwing another 2 tasks...\n");
add_task(pool, mytask, (void *)(rand() % 10));
add_task(pool, mytask, (void *)(rand() % 10));
add_thread(pool, 2);
sleep(5);
printf("remove 3 threads from the pool, "
"current thread number: %d\n",
remove_thread(pool, 3));
destroy_pool(pool);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!