【无标题】

线程池的实现

#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>

#define DEFAULT_TIME 10        /*10s检测一次*/
#define MIN_WAIT_TASK_NUM 10   /*如果queue_size > MIN_WAIT_TASK_NUM 添加新的线程到线程池*/
#define DEFAULT_THREAD_VARY 10 /*每次创建和销毁线程的个数*/
#define true 1
#define false 0

typedef struct
{
    void *(*function)(void *); /* 函数指针,回调函数 */
    void *arg;                 /* 上面函数的参数 */
} threadpool_task_t;           /* 各子线程任务结构体 */

/* 描述线程池相关信息 */

typedef struct threadpool_t
{
    pthread_mutex_t lock;           /* 用于锁住本结构体 */
    pthread_mutex_t thread_counter; /* 记录忙状态线程个数de琐 -- busy_thr_num */

    pthread_cond_t queue_not_full;  /* 当任务队列满时,添加任务的线程阻塞,等待此条件变量 */
    pthread_cond_t queue_not_empty; /* 任务队列里不为空时,通知等待任务的线程 */

    pthread_t *threads;            /* 存放线程池中每个线程的tid。数组 */
    pthread_t adjust_tid;          /* 存管理线程tid */
    threadpool_task_t *task_queue; /* 任务队列(数组首地址) */

    int min_thr_num;       /* 线程池最小线程数 */
    int max_thr_num;       /* 线程池最大线程数 */
    int live_thr_num;      /* 当前存活线程个数 */
    int busy_thr_num;      /* 忙状态线程个数 */
    int wait_exit_thr_num; /* 要销毁的线程个数 */

    int queue_front;    /* task_queue队头下标 */
    int queue_rear;     /* task_queue队尾下标 */
    int queue_size;     /* task_queue队中实际任务数 */
    int queue_max_size; /* task_queue队列可容纳任务数上限 */

    int shutdown; /* 标志位,线程池使用状态,true或false */
} threadpool_t;

void *threadpool_thread(void *threadpool);

void *adjust_thread(void *threadpool);

int is_thread_alive(pthread_t tid);
int threadpool_free(threadpool_t *pool);

//threadpool_create(3,100,100);
threadpool_t *threadpool_create(int min_thr_num, int max_thr_num, int queue_max_size)
{
    int i;
    threadpool_t *pool = NULL; /* 线程池 结构体 */
    do
    {
        pool = (threadpool_t *)malloc(sizeof(threadpool_t));
        if (!pool)
        {
            break;
        }
        pool->shutdown = false;
        pool->queue_front = 0;
        pool->queue_rear = 0;
        pool->queue_max_size = queue_max_size;
        pool->queue_size = 0;

        pool->busy_thr_num = 0;
        pool->live_thr_num = min_thr_num;
        pool->wait_exit_thr_num = 0;
        pool->max_thr_num = max_thr_num;
        pool->min_thr_num = min_thr_num;

        if (pthread_mutex_init(&(pool->thread_counter), NULL) != 0 || pthread_mutex_init(&(pool->lock), NULL) != 0 || pthread_cond_init(&(pool->queue_not_empty), NULL) != 0 || pthread_cond_init(&(pool->queue_not_full), NULL) != 0)
        {
            printf("init quqeue or cond failed\n");
            break;
        }
        pool->task_queue = (threadpool_task_t *)malloc(sizeof(threadpool_task_t) * (pool->queue_max_size));
        if (!pool->task_queue)
        {
            printf("task_queue:malloc error\n");
            break;
        }
        memset(pool->task_queue, 0, sizeof(threadpool_task_t) * (pool->queue_max_size));
        pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * (pool->max_thr_num));
        if (!pool->threads)
        {
            printf("threads:malloc error\n");
            break;
        }
        memset(pool->threads, 0, sizeof(pthread_t) * (pool->max_thr_num));
        for (size_t i = 0; i < pool->min_thr_num; i++)
        {
            int r = pthread_create(&(pool->threads[i]), NULL, threadpool_thread, (void *)pool);
            if (r != 0)
            {
                printf("pthread_create error:%s\n", strerror(r));
                break;
            }
        }
        int r = pthread_create(&(pool->adjust_tid), NULL, adjust_thread, (void *)pool);
        if (r != 0)
        {
            printf("pthread_create error:%s\n", strerror(r));
            break;
        }
        return pool;

    } while (0);
    threadpool_destroy(pool);

    return NULL;
}

/* 向线程池中 添加一个任务 */
//threadpool_add(thp, process, (void*)&num[i]);   /* 向线程池中添加任务 process: 小写---->大写*/

int threadpool_add(threadpool_t *pool, void *(*function)(void *arg), void *arg)
{
    pthread_mutex_lock(&(pool->lock));
    while ((pool->queue_size == pool->queue_max_size) && (pool->shutdown == false))
    {
        pthread_cond_wait(&(pool->queue_not_full), &(pool->lock));
    }
    if(pool->shutdown){
    pthread_mutex_unlock(&(pool->lock));

        return -1;
    }
    pool->task_queue[pool->queue_rear].function = function;
    pool->task_queue[pool->queue_rear].arg = arg;
    int x = (++(pool->queue_rear)) % (pool->queue_max_size);
    pool->queue_rear = x;
    pool->queue_size++;
    pthread_cond_signal(&(pool->queue_not_empty));
    pthread_mutex_unlock(&(pool->lock));

    return 0;
}

/* 线程池中各个工作线程 */
void *threadpool_thread(void *threadpool)
{
    threadpool_t *pool = (threadpool_t *)threadpool;
    for (;;)
    {
        pthread_mutex_lock(&(pool->lock));
        while ((pool->queue_size == 0) && (pool->shutdown == false))
        {
            printf("thread %#X is waiting...\n", (unsigned long)pthread_self());
            pthread_cond_wait(&(pool->queue_not_empty), &(pool->lock));
            if (pool->wait_exit_thr_num > 0)
            {
                pool->wait_exit_thr_num--;
                if (pool->live_thr_num > pool->min_thr_num)
                {
                    pool->live_thr_num--;
                    pthread_mutex_unlock(&(pool->lock));
                    pthread_detach(pthread_self());
                    pthread_exit(NULL);
                }
            }
        }
        if (pool->shutdown)
        {
            pthread_mutex_unlock(&(pool->lock));
            pthread_detach(pthread_self());
            pthread_exit(NULL);
        }
        threadpool_task_t t = pool->task_queue[pool->queue_front];
        int x = (++(pool->queue_front)) % (pool->queue_max_size);
        pool->queue_front = x;
        pool->queue_size--;
        pthread_cond_signal(&(pool->queue_not_full));
        pthread_mutex_unlock(&(pool->lock));
        pthread_mutex_lock(&(pool->thread_counter));
        pool->busy_thr_num++;
        pthread_mutex_unlock(&(pool->thread_counter));
        printf("thread %#X is doing task...\n", (unsigned long)pthread_self());
        t.function(t.arg);
        printf("thread %#X has finished task...\n", (unsigned long)pthread_self());
        pthread_mutex_lock(&(pool->thread_counter));
        pool->busy_thr_num--;
        pthread_mutex_unlock(&(pool->thread_counter));
    }
}

/* 管理线程 */
void *adjust_thread(void *threadpool)
{
    threadpool_t *pool = (threadpool_t *)threadpool;
    for (;;)
    {
        sleep(DEFAULT_TIME);
        pthread_mutex_lock(&(pool->lock));
        if (pool->shutdown)
        {
            break;
        }
        //扩容
        if (pool->busy_thr_num * 4 > pool->live_thr_num * 5 && pool->live_thr_num < pool->max_thr_num)
        {
            printf("reduce thread...\n");
        }
        //瘦身
        if (pool->wait_exit_thr_num == 0)
        {
            if (pool->busy_thr_num * 3 < pool->live_thr_num && pool->live_thr_num > pool->min_thr_num)
            {
                printf("increase thread...\n");
                pool->wait_exit_thr_num = DEFAULT_THREAD_VARY;
                for (size_t i = 0; i < pool->wait_exit_thr_num; i++)
                {
                    pthread_cond_signal(&(pool->queue_not_empty));
                }
            }
        }
    }

    return NULL;
}

int threadpool_destroy(threadpool_t *pool)
{
    if (!pool)
    {
        return -1;
    }
    pthread_kill(pool->adjust_tid, 0);
    pthread_join(pool->adjust_tid, NULL);
    for (int i = 0; i < pool->live_thr_num; i++)
    {
        pthread_cond_broadcast(&(pool->queue_not_empty));
    };
    for (int i = 0; i < pool->live_thr_num; i++)
    {
        pthread_join(pool->threads[i], NULL);
    }
    return 0;
}

int threadpool_free(threadpool_t *pool)
{
    if (!pool)
    {
        return -1;
    }
    pthread_mutex_lock(&(pool->lock));
    pool->shutdown = true;
    pthread_mutex_unlock(&(pool->lock));
    if (pool->threads)
    {
        free(pool->threads);
    }
    if (pool->task_queue)
    {
        free(pool->task_queue);
    }
    pthread_mutex_destroy(&(pool->lock));
    pthread_mutex_destroy(&(pool->thread_counter));
    pthread_cond_destroy(&(pool->queue_not_empty));
    pthread_cond_destroy(&(pool->queue_not_full));
    free(pool);
}

int threadpool_all_threadnum(threadpool_t *pool)
{
    threadpool_t *threadpool = (threadpool_t *)pool;
    pthread_mutex_lock(&(threadpool->lock));
    int x = threadpool->live_thr_num;
    pthread_mutex_unlock(&(threadpool->lock));
    return x;
}

int threadpool_busy_threadnum(threadpool_t *pool)
{
    threadpool_t *threadpool = (threadpool_t *)pool;
    pthread_mutex_lock(&(threadpool->lock));
    int x = threadpool->busy_thr_num;
    pthread_mutex_unlock(&(threadpool->lock));
    return x;
}

int is_thread_alive(pthread_t tid)
{
}

/*测试*/

#if 1

/* 线程池中的线程,模拟处理业务 */
void *process(void *arg)
{

    return NULL;
}

int main(void)
{
    return 0;
}

#endif

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值