浅谈线程池与实现(C)

浅谈线程池:

线程池是一个使用多线程来处理一个可并行执行的任务。
可并行执行的任务就是一个任务可以拆分很多部分,每个部分可以同时进行处理,所有部分处理完后整个任务也就处理完成。(相当于生产一个玩具,可以拆开很多部分,每个部件不一定是按着顺序生产,但是只要生产完成了,这个玩具就完成了)
线程池内部会启动多个线程,每个线程都可以执行独立的工作,互相之间可以联系,也可以没有联系。
线程中通过线程的互斥和同步技术来实现任务之间互相配合

线程池内部组件

//最大等待任务数
#define MAX_WAITING_TASKS 2000
//最大活动线程数
#define MAX_ACTIVE_THREADS 20

//任务链表节点
typedef struct task{
    void *(*task_func)(void *arg);//任务处理函数
    void *arg;//任务处理函数的参数

    struct task *next;//单链表
}task_t;

//线程池
typedef struct thread_pool{
    pthread_mutex_t lock;//互斥锁
    pthread_cond_t cond;//条件变量

    task_t *task_list;//任务链表

    int shutdown;//结束标志

    unsigned int max_waiting_tasks;//最大等待任务数
    unsigned int current_waiting_tasks;//当前等待任务数
    unsigned int max_active_threads;//最大活动线程数
    unsigned int current_active_threads;//当前活动线程数

    pthread_t id[MAX_ACTIVE_THREADS];
}thread_pool_t;

线程函数与线程退出处理函数

//线程退出处理函数
void func(void *arg)
{
    printf("线程%lu退出处理!\n",pthread_self());
    //解锁
    pthread_mutex_unlock((pthread_mutex_t *)arg);
}

//线程函数
void *start_routine(void *arg)
{
    task_t *p = NULL;

    thread_pool_t *thread_pool = (thread_pool_t *)arg;

    pthread_cleanup_push(func,&thread_pool->lock);

    while(1){
        //加锁
        pthread_mutex_lock(&thread_pool->lock);
        //如果无任务可执行,也没有退出标志,睡眠等待唤醒
        if(thread_pool->current_waiting_tasks==0&&thread_pool->shutdown==0){
            pthread_cond_wait(&thread_pool->cond,&thread_pool->lock);
        }

        //没有任务,但是有退出标志
        if(thread_pool->current_waiting_tasks==0&&thread_pool->shutdown!=0){
            pthread_exit(NULL);
        }

        //有任务,执行任务
        //不允许退出
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);

        p = thread_pool->task_list->next;//链表中取出一个任务
        if(!p){
            printf("task_list error!\n");
            pthread_mutex_unlock(&thread_pool->lock);
            continue;
        }
        //从链表中删掉任务
        thread_pool->task_list->next = p->next;
        //当前等待任务数-1
        thread_pool->current_waiting_tasks--;

        //解锁
        pthread_mutex_unlock(&thread_pool->lock);
        //执行任务处理函数
        p->task_func(p->arg);
        //释放p
        free(p);

        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
    }

    pthread_exit(NULL);
    pthread_cleanup_pop(0);
}

线程池相关对外接口

  • 初始化线程池
    参数:
    thread_pool:线程池
    thread_num:线程池线程数量
    返回值:
    成功返回0,失败返回-1
int init_thread_pool(thread_pool_t *thread_pool,int threads_num)
{
    if(threads_num>MAX_ACTIVE_THREADS){
        printf("too many threads_num!\n");
        return -1;
    }

    //初始化互斥锁和条件变量
    pthread_mutex_init(&thread_pool->lock,NULL);
    pthread_cond_init(&thread_pool->cond,NULL);

    //初始化任务链表
    thread_pool->task_list = (task_t *)malloc(sizeof(task_t));
    if(!thread_pool->task_list){
        perror("malloc");
        return -1;
    }

    thread_pool->task_list->next = NULL;

    //初始化结束标志
    thread_pool->shutdown = 0;//不结束

    //最大等待任务数
    thread_pool->max_waiting_tasks = MAX_WAITING_TASKS;
    //当前等待任务数
    thread_pool->current_waiting_tasks = 0;
    //最大活动线程数
    thread_pool->max_active_threads = MAX_ACTIVE_THREADS;
    //当前活动线程数
    thread_pool->current_active_threads = threads_num;

    //创建线程
    int i = 0;
    for(i=0;i<threads_num;i++){
        pthread_create(&thread_pool->id[i],NULL,start_routine,(void *)thread_pool);
        printf("%lu线程开始!\n",thread_pool->id[i]);
    }
   
    return 0;
}
  • 添加任务
    参数:
    thread_pool:线程池
    task_func(void arg) :线程函数
    arg:传入线程函数的参数
    返回值:
    成功返回0,失败返回-1
int add_task(thread_pool_t *thread_pool,void *(*task_func)(void *arg),void *arg)
{
    if(thread_pool->current_waiting_tasks>=thread_pool->max_waiting_tasks){
        printf("too many tasks!\n");
        return -1;
    }

    //构造节点
    task_t *new_task = (task_t *)malloc(sizeof(task_t));
    if(!new_task){
        perror("malloc");
        return -1;
    }

    //初始化节点
    new_task->task_func = task_func;
    new_task->arg = arg;

    //将节点插入链表
    //加锁
    pthread_mutex_lock(&thread_pool->lock);
    //插入链表尾部
    task_t *tail = thread_pool->task_list;
    while(tail->next)
        tail = tail->next;

    tail->next = new_task;
    new_task->next = NULL;
    //等待任务数+1
    thread_pool->current_waiting_tasks++;
    //解锁
    pthread_mutex_unlock(&thread_pool->lock);

    //唤醒一个等待的线程
    pthread_cond_signal(&thread_pool->cond);

    return 0;
}
  • 添加线程
    参数
    thread_pool:线程池
    num:想要添加的线程数目
    返回值:
    成功返回添加线程后的当前线程数目
    失败返回0
int add_thread(thread_pool_t *thread_pool,int num)
{
    //添加线程后的总线程数
    unsigned total_treads = 0;

    //如果num不合法或者已经达到最大线程数,直接返回
    if(num<=0||thread_pool->current_active_threads>=thread_pool->max_active_threads)
        return 0;

    if(thread_pool->current_active_threads+num>thread_pool->max_active_threads){
        total_treads = thread_pool->max_active_threads;
    }
    else{
        total_treads = thread_pool->current_active_threads+num;
    }

    //创建线程
    int i = 0,inc_threads = 0;
    for(i=thread_pool->current_active_threads;i<total_treads;i++){
        pthread_create(&thread_pool->id[i],NULL,start_routine,(void *)thread_pool);
        //增加线程数+1
        inc_threads++;
        printf("线程%lu创建成功!\n",thread_pool->id[i]);
    }

    thread_pool->current_active_threads += inc_threads;
    //返回添加的线程数

    return inc_threads;
}
  • 删除线程
    参数:
    thread_pool:线程池
    num:想要删除的线程数目
    返回值:
    成功返回删除线程后当前的线程数目
    失败返回0
int del_thread(thread_pool_t *thread_pool,int num)
{
    //删除线程后的总线程数
    unsigned total_treads = 0;

    //如果num不合法或者已经只有一个线程,直接返回
    if(num<=0||thread_pool->current_active_threads==1)
        return 0;

    //至少保留一个线程
    if(thread_pool->current_active_threads-num<1){
        total_treads = 1;
    }
    else{
        total_treads = thread_pool->current_active_threads-num;
    }

    //删除数组最后指定个数的线程
    int i = 0;
    for(i=thread_pool->current_active_threads-1;i>total_treads-1;i--){
        pthread_cancel(thread_pool->id[i]);
        printf("线程%lu被取消!\n",thread_pool->id[i]);
    }

    //更新当前活动线程数
    return thread_pool->current_active_threads = total_treads;
}
  • 销毁线程池
    参数:
    thread_pool:线程池
int destroy_thread_pool(thread_pool_t *thread_pool)
{
    //设置结束标志
    thread_pool->shutdown = 1;
    //唤醒所有睡眠的线程
    pthread_cond_broadcast(&thread_pool->cond);

    //等待所有线程就结束,回收结束线程的资源
    int i;
    for(i=0;i<thread_pool->current_active_threads;i++){
        pthread_join(thread_pool->id[i],NULL);
        printf("%lu线程结束!\n",thread_pool->id[i]);
    }

    //销毁链表
    free(thread_pool->task_list);
    thread_pool->task_list = NULL;

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值