|
|
@ -16,278 +16,303 @@
|
|
|
|
Author: Xie Han (xiehan@sogou-inc.com)
|
|
|
|
Author: Xie Han (xiehan@sogou-inc.com)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <errno.h> // 包含错误号定义
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <pthread.h> // 包含POSIX线程库
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdlib.h> // 包含标准库函数,如malloc和free
|
|
|
|
#include "msgqueue.h"
|
|
|
|
#include "msgqueue.h" // 包含消息队列的实现,用于线程间通信
|
|
|
|
#include "thrdpool.h"
|
|
|
|
#include "thrdpool.h" // 包含线程池的声明
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 线程池结构体定义
|
|
|
|
struct __thrdpool
|
|
|
|
struct __thrdpool
|
|
|
|
{
|
|
|
|
{
|
|
|
|
msgqueue_t *msgqueue;
|
|
|
|
msgqueue_t* msgqueue; // 消息队列,用于存放待执行的任务
|
|
|
|
size_t nthreads;
|
|
|
|
size_t nthreads; // 线程池中的线程数量
|
|
|
|
size_t stacksize;
|
|
|
|
size_t stacksize; // 线程栈的大小
|
|
|
|
pthread_t tid;
|
|
|
|
pthread_t tid; // 线程ID
|
|
|
|
pthread_mutex_t mutex;
|
|
|
|
pthread_mutex_t mutex; // 互斥锁,用于保护线程池的共享数据
|
|
|
|
pthread_key_t key;
|
|
|
|
pthread_key_t key; // 线程局部存储的键
|
|
|
|
pthread_cond_t *terminate;
|
|
|
|
pthread_cond_t* terminate; // 条件变量,用于通知线程退出
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 任务条目结构体定义
|
|
|
|
struct __thrdpool_task_entry
|
|
|
|
struct __thrdpool_task_entry
|
|
|
|
{
|
|
|
|
{
|
|
|
|
void *link;
|
|
|
|
void* link; // 链接到下一个任务条目
|
|
|
|
struct thrdpool_task task;
|
|
|
|
struct thrdpool_task task; // 任务结构体,包含任务函数和上下文
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 静态变量,用于表示一个空的线程ID
|
|
|
|
static pthread_t __zero_tid;
|
|
|
|
static pthread_t __zero_tid;
|
|
|
|
|
|
|
|
|
|
|
|
static void __thrdpool_exit_routine(void *context)
|
|
|
|
// 线程退出时的回调函数
|
|
|
|
|
|
|
|
static void __thrdpool_exit_routine(void* context)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
thrdpool_t *pool = (thrdpool_t *)context;
|
|
|
|
thrdpool_t* pool = (thrdpool_t*)context;
|
|
|
|
pthread_t tid;
|
|
|
|
pthread_t tid;
|
|
|
|
|
|
|
|
|
|
|
|
/* One thread joins another. Don't need to keep all thread IDs. */
|
|
|
|
// 锁定互斥锁
|
|
|
|
pthread_mutex_lock(&pool->mutex);
|
|
|
|
pthread_mutex_lock(&pool->mutex);
|
|
|
|
tid = pool->tid;
|
|
|
|
tid = pool->tid;
|
|
|
|
pool->tid = pthread_self();
|
|
|
|
pool->tid = pthread_self();
|
|
|
|
if (--pool->nthreads == 0 && pool->terminate)
|
|
|
|
if (--pool->nthreads == 0 && pool->terminate)
|
|
|
|
pthread_cond_signal(pool->terminate);
|
|
|
|
pthread_cond_signal(pool->terminate);
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&pool->mutex);
|
|
|
|
pthread_mutex_unlock(&pool->mutex);
|
|
|
|
if (!pthread_equal(tid, __zero_tid))
|
|
|
|
// 如果不是零ID,则等待线程结束
|
|
|
|
pthread_join(tid, NULL);
|
|
|
|
if (!pthread_equal(tid, __zero_tid))
|
|
|
|
|
|
|
|
pthread_join(tid, NULL);
|
|
|
|
pthread_exit(NULL);
|
|
|
|
|
|
|
|
|
|
|
|
pthread_exit(NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void *__thrdpool_routine(void *arg)
|
|
|
|
// 线程池的线程函数
|
|
|
|
|
|
|
|
static void* __thrdpool_routine(void* arg)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
thrdpool_t *pool = (thrdpool_t *)arg;
|
|
|
|
thrdpool_t* pool = (thrdpool_t*)arg;
|
|
|
|
struct __thrdpool_task_entry *entry;
|
|
|
|
struct __thrdpool_task_entry* entry;
|
|
|
|
void (*task_routine)(void *);
|
|
|
|
void (*task_routine)(void*);
|
|
|
|
void *task_context;
|
|
|
|
void* task_context;
|
|
|
|
|
|
|
|
|
|
|
|
pthread_setspecific(pool->key, pool);
|
|
|
|
// 设置线程局部存储
|
|
|
|
while (!pool->terminate)
|
|
|
|
pthread_setspecific(pool->key, pool);
|
|
|
|
{
|
|
|
|
while (!pool->terminate)
|
|
|
|
entry = (struct __thrdpool_task_entry *)msgqueue_get(pool->msgqueue);
|
|
|
|
{
|
|
|
|
if (!entry)
|
|
|
|
// 从消息队列中获取任务
|
|
|
|
break;
|
|
|
|
entry = (struct __thrdpool_task_entry*)msgqueue_get(pool->msgqueue);
|
|
|
|
|
|
|
|
if (!entry)
|
|
|
|
task_routine = entry->task.routine;
|
|
|
|
break;
|
|
|
|
task_context = entry->task.context;
|
|
|
|
|
|
|
|
free(entry);
|
|
|
|
// 执行任务
|
|
|
|
task_routine(task_context);
|
|
|
|
task_routine = entry->task.routine;
|
|
|
|
|
|
|
|
task_context = entry->task.context;
|
|
|
|
if (pool->nthreads == 0)
|
|
|
|
free(entry);
|
|
|
|
{
|
|
|
|
task_routine(task_context);
|
|
|
|
/* Thread pool was destroyed by the task. */
|
|
|
|
|
|
|
|
free(pool);
|
|
|
|
// 如果线程池中的线程数量为0,则线程池已被销毁
|
|
|
|
return NULL;
|
|
|
|
if (pool->nthreads == 0)
|
|
|
|
}
|
|
|
|
{
|
|
|
|
}
|
|
|
|
free(pool);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
__thrdpool_exit_routine(pool);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 执行线程退出时的操作
|
|
|
|
|
|
|
|
__thrdpool_exit_routine(pool);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void __thrdpool_terminate(int in_pool, thrdpool_t *pool)
|
|
|
|
// 线程池销毁函数
|
|
|
|
|
|
|
|
static void __thrdpool_terminate(int in_pool, thrdpool_t* pool)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_cond_t term = PTHREAD_COND_INITIALIZER;
|
|
|
|
pthread_cond_t term = PTHREAD_COND_INITIALIZER;
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&pool->mutex);
|
|
|
|
// 锁定互斥锁
|
|
|
|
msgqueue_set_nonblock(pool->msgqueue);
|
|
|
|
pthread_mutex_lock(&pool->mutex);
|
|
|
|
pool->terminate = &term;
|
|
|
|
msgqueue_set_nonblock(pool->msgqueue);
|
|
|
|
|
|
|
|
pool->terminate = &term;
|
|
|
|
if (in_pool)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (in_pool)
|
|
|
|
/* Thread pool destroyed in a pool thread is legal. */
|
|
|
|
{
|
|
|
|
pthread_detach(pthread_self());
|
|
|
|
// 如果在线程池的线程中销毁线程池,则分离当前线程
|
|
|
|
pool->nthreads--;
|
|
|
|
pthread_detach(pthread_self());
|
|
|
|
}
|
|
|
|
pool->nthreads--;
|
|
|
|
|
|
|
|
}
|
|
|
|
while (pool->nthreads > 0)
|
|
|
|
|
|
|
|
pthread_cond_wait(&term, &pool->mutex);
|
|
|
|
// 等待所有线程结束
|
|
|
|
|
|
|
|
while (pool->nthreads > 0)
|
|
|
|
pthread_mutex_unlock(&pool->mutex);
|
|
|
|
pthread_cond_wait(&term, &pool->mutex);
|
|
|
|
if (!pthread_equal(pool->tid, __zero_tid))
|
|
|
|
|
|
|
|
pthread_join(pool->tid, NULL);
|
|
|
|
pthread_mutex_unlock(&pool->mutex);
|
|
|
|
|
|
|
|
// 如果不是零ID,则等待线程结束
|
|
|
|
|
|
|
|
if (!pthread_equal(pool->tid, __zero_tid))
|
|
|
|
|
|
|
|
pthread_join(pool->tid, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int __thrdpool_create_threads(size_t nthreads, thrdpool_t *pool)
|
|
|
|
// 线程池创建线程函数
|
|
|
|
|
|
|
|
static int __thrdpool_create_threads(size_t nthreads, thrdpool_t* pool)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_attr_t attr;
|
|
|
|
pthread_attr_t attr;
|
|
|
|
pthread_t tid;
|
|
|
|
pthread_t tid;
|
|
|
|
int ret;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
|
|
ret = pthread_attr_init(&attr);
|
|
|
|
// 初始化线程属性
|
|
|
|
if (ret == 0)
|
|
|
|
ret = pthread_attr_init(&attr);
|
|
|
|
{
|
|
|
|
if (ret == 0)
|
|
|
|
if (pool->stacksize)
|
|
|
|
{
|
|
|
|
pthread_attr_setstacksize(&attr, pool->stacksize);
|
|
|
|
if (pool->stacksize)
|
|
|
|
|
|
|
|
pthread_attr_setstacksize(&attr, pool->stacksize);
|
|
|
|
while (pool->nthreads < nthreads)
|
|
|
|
|
|
|
|
{
|
|
|
|
while (pool->nthreads < nthreads)
|
|
|
|
ret = pthread_create(&tid, &attr, __thrdpool_routine, pool);
|
|
|
|
{
|
|
|
|
if (ret == 0)
|
|
|
|
// 创建线程
|
|
|
|
pool->nthreads++;
|
|
|
|
ret = pthread_create(&tid, &attr, __thrdpool_routine, pool);
|
|
|
|
else
|
|
|
|
if (ret == 0)
|
|
|
|
break;
|
|
|
|
pool->nthreads++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
|
|
|
|
break;
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
}
|
|
|
|
if (pool->nthreads == nthreads)
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
|
|
|
|
if (pool->nthreads == nthreads)
|
|
|
|
__thrdpool_terminate(0, pool);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果创建失败,则销毁线程池
|
|
|
|
errno = ret;
|
|
|
|
__thrdpool_terminate(0, pool);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
errno = ret;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
thrdpool_t *thrdpool_create(size_t nthreads, size_t stacksize)
|
|
|
|
// 创建线程池
|
|
|
|
|
|
|
|
thrdpool_t* thrdpool_create(size_t nthreads, size_t stacksize)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
thrdpool_t *pool;
|
|
|
|
thrdpool_t* pool;
|
|
|
|
int ret;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
|
|
pool = (thrdpool_t *)malloc(sizeof (thrdpool_t));
|
|
|
|
pool = (thrdpool_t*)malloc(sizeof(thrdpool_t)); // 分配线程池结构体内存
|
|
|
|
if (!pool)
|
|
|
|
if (!pool)
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
pool->msgqueue = msgqueue_create(0, 0);
|
|
|
|
pool->msgqueue = msgqueue_create(0, 0); // 创建消息队列
|
|
|
|
if (pool->msgqueue)
|
|
|
|
if (pool->msgqueue)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ret = pthread_mutex_init(&pool->mutex, NULL);
|
|
|
|
ret = pthread_mutex_init(&pool->mutex, NULL); // 初始化互斥锁
|
|
|
|
if (ret == 0)
|
|
|
|
if (ret == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ret = pthread_key_create(&pool->key, NULL);
|
|
|
|
ret = pthread_key_create(&pool->key, NULL); // 创建线程局部存储键
|
|
|
|
if (ret == 0)
|
|
|
|
if (ret == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pool->stacksize = stacksize;
|
|
|
|
pool->stacksize = stacksize; // 设置线程栈大小
|
|
|
|
pool->nthreads = 0;
|
|
|
|
pool->nthreads = 0; // 初始化线程数量
|
|
|
|
pool->tid = __zero_tid;
|
|
|
|
pool->tid = __zero_tid; // 初始化线程ID
|
|
|
|
pool->terminate = NULL;
|
|
|
|
pool->terminate = NULL; // 初始化终止条件
|
|
|
|
if (__thrdpool_create_threads(nthreads, pool) >= 0)
|
|
|
|
if (__thrdpool_create_threads(nthreads, pool) >= 0) // 创建线程
|
|
|
|
return pool;
|
|
|
|
return pool;
|
|
|
|
|
|
|
|
|
|
|
|
pthread_key_delete(pool->key);
|
|
|
|
pthread_key_delete(pool->key); // 删除线程局部存储键
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_destroy(&pool->mutex);
|
|
|
|
pthread_mutex_destroy(&pool->mutex); // 销毁互斥锁
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
errno = ret;
|
|
|
|
errno = ret; // 设置错误号
|
|
|
|
msgqueue_destroy(pool->msgqueue);
|
|
|
|
msgqueue_destroy(pool->msgqueue); // 销毁消息队列
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
free(pool);
|
|
|
|
free(pool); // 释放线程池结构体内存
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline void __thrdpool_schedule(const struct thrdpool_task *task, void *buf,
|
|
|
|
// 内部函数,用于将任务调度到线程池
|
|
|
|
thrdpool_t *pool);
|
|
|
|
inline void __thrdpool_schedule(const struct thrdpool_task* task, void* buf,
|
|
|
|
|
|
|
|
thrdpool_t* pool);
|
|
|
|
|
|
|
|
|
|
|
|
void __thrdpool_schedule(const struct thrdpool_task *task, void *buf,
|
|
|
|
void __thrdpool_schedule(const struct thrdpool_task* task, void* buf,
|
|
|
|
thrdpool_t *pool)
|
|
|
|
thrdpool_t* pool)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
((struct __thrdpool_task_entry *)buf)->task = *task;
|
|
|
|
((struct __thrdpool_task_entry*)buf)->task = *task; // 设置任务
|
|
|
|
msgqueue_put(buf, pool->msgqueue);
|
|
|
|
msgqueue_put(buf, pool->msgqueue); // 将任务放入消息队列
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int thrdpool_schedule(const struct thrdpool_task *task, thrdpool_t *pool)
|
|
|
|
// 调度任务到线程池
|
|
|
|
|
|
|
|
int thrdpool_schedule(const struct thrdpool_task* task, thrdpool_t* pool)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
void *buf = malloc(sizeof (struct __thrdpool_task_entry));
|
|
|
|
void* buf = malloc(sizeof(struct __thrdpool_task_entry)); // 分配任务条目内存
|
|
|
|
|
|
|
|
|
|
|
|
if (buf)
|
|
|
|
if (buf)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
__thrdpool_schedule(task, buf, pool);
|
|
|
|
__thrdpool_schedule(task, buf, pool); // 调度任务
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline int thrdpool_in_pool(thrdpool_t *pool);
|
|
|
|
// 判断当前线程是否在线程池中
|
|
|
|
|
|
|
|
inline int thrdpool_in_pool(thrdpool_t* pool);
|
|
|
|
|
|
|
|
|
|
|
|
int thrdpool_in_pool(thrdpool_t *pool)
|
|
|
|
int thrdpool_in_pool(thrdpool_t* pool)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return pthread_getspecific(pool->key) == pool;
|
|
|
|
return pthread_getspecific(pool->key) == pool; // 通过线程局部存储判断
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int thrdpool_increase(thrdpool_t *pool)
|
|
|
|
// 增加线程池中的线程数量
|
|
|
|
|
|
|
|
int thrdpool_increase(thrdpool_t* pool)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_attr_t attr;
|
|
|
|
pthread_attr_t attr;
|
|
|
|
pthread_t tid;
|
|
|
|
pthread_t tid;
|
|
|
|
int ret;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
|
|
ret = pthread_attr_init(&attr);
|
|
|
|
ret = pthread_attr_init(&attr); // 初始化线程属性
|
|
|
|
if (ret == 0)
|
|
|
|
if (ret == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (pool->stacksize)
|
|
|
|
if (pool->stacksize)
|
|
|
|
pthread_attr_setstacksize(&attr, pool->stacksize);
|
|
|
|
pthread_attr_setstacksize(&attr, pool->stacksize); // 设置线程栈大小
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&pool->mutex);
|
|
|
|
pthread_mutex_lock(&pool->mutex); // 锁定互斥锁
|
|
|
|
ret = pthread_create(&tid, &attr, __thrdpool_routine, pool);
|
|
|
|
ret = pthread_create(&tid, &attr, __thrdpool_routine, pool); // 创建线程
|
|
|
|
if (ret == 0)
|
|
|
|
if (ret == 0)
|
|
|
|
pool->nthreads++;
|
|
|
|
pool->nthreads++; // 增加线程数量
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&pool->mutex);
|
|
|
|
pthread_mutex_unlock(&pool->mutex); // 解锁互斥锁
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
pthread_attr_destroy(&attr); // 销毁线程属性
|
|
|
|
if (ret == 0)
|
|
|
|
if (ret == 0)
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
errno = ret;
|
|
|
|
errno = ret; // 设置错误号
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int thrdpool_decrease(thrdpool_t *pool)
|
|
|
|
// 减少线程池中的线程数量
|
|
|
|
|
|
|
|
int thrdpool_decrease(thrdpool_t* pool)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
void *buf = malloc(sizeof (struct __thrdpool_task_entry));
|
|
|
|
void* buf = malloc(sizeof(struct __thrdpool_task_entry)); // 分配任务条目内存
|
|
|
|
struct __thrdpool_task_entry *entry;
|
|
|
|
struct __thrdpool_task_entry* entry;
|
|
|
|
|
|
|
|
|
|
|
|
if (buf)
|
|
|
|
if (buf)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
entry = (struct __thrdpool_task_entry *)buf;
|
|
|
|
entry = (struct __thrdpool_task_entry*)buf;
|
|
|
|
entry->task.routine = __thrdpool_exit_routine;
|
|
|
|
entry->task.routine = __thrdpool_exit_routine; // 设置退出任务
|
|
|
|
entry->task.context = pool;
|
|
|
|
entry->task.context = pool;
|
|
|
|
msgqueue_put_head(entry, pool->msgqueue);
|
|
|
|
msgqueue_put_head(entry, pool->msgqueue); // 将退出任务放入消息队列头部
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void thrdpool_exit(thrdpool_t *pool)
|
|
|
|
// 线程池中的线程退出
|
|
|
|
|
|
|
|
void thrdpool_exit(thrdpool_t* pool)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (thrdpool_in_pool(pool))
|
|
|
|
if (thrdpool_in_pool(pool)) // 如果当前线程在线程池中
|
|
|
|
__thrdpool_exit_routine(pool);
|
|
|
|
__thrdpool_exit_routine(pool); // 执行退出操作
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void thrdpool_destroy(void (*pending)(const struct thrdpool_task *),
|
|
|
|
// 销毁线程池
|
|
|
|
thrdpool_t *pool)
|
|
|
|
void thrdpool_destroy(void (*pending)(const struct thrdpool_task*),
|
|
|
|
|
|
|
|
thrdpool_t* pool)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int in_pool = thrdpool_in_pool(pool);
|
|
|
|
int in_pool = thrdpool_in_pool(pool); // 判断是否在线程池中
|
|
|
|
struct __thrdpool_task_entry *entry;
|
|
|
|
struct __thrdpool_task_entry* entry;
|
|
|
|
|
|
|
|
|
|
|
|
__thrdpool_terminate(in_pool, pool);
|
|
|
|
__thrdpool_terminate(in_pool, pool); // 终止线程池
|
|
|
|
while (1)
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
entry = (struct __thrdpool_task_entry *)msgqueue_get(pool->msgqueue);
|
|
|
|
entry = (struct __thrdpool_task_entry*)msgqueue_get(pool->msgqueue); // 获取任务
|
|
|
|
if (!entry)
|
|
|
|
if (!entry)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
if (pending && entry->task.routine != __thrdpool_exit_routine)
|
|
|
|
if (pending && entry->task.routine != __thrdpool_exit_routine) // 如果有挂起任务处理函数
|
|
|
|
pending(&entry->task);
|
|
|
|
pending(&entry->task); // 处理挂起任务
|
|
|
|
|
|
|
|
|
|
|
|
free(entry);
|
|
|
|
free(entry); // 释放任务条目内存
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pthread_key_delete(pool->key);
|
|
|
|
pthread_key_delete(pool->key); // 删除线程局部存储键
|
|
|
|
pthread_mutex_destroy(&pool->mutex);
|
|
|
|
pthread_mutex_destroy(&pool->mutex); // 销毁互斥锁
|
|
|
|
msgqueue_destroy(pool->msgqueue);
|
|
|
|
msgqueue_destroy(pool->msgqueue); // 销毁消息队列
|
|
|
|
if (!in_pool)
|
|
|
|
if (!in_pool) // 如果不在线程池中,释放线程池结构体内存
|
|
|
|
free(pool);
|
|
|
|
free(pool);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|