lgy514

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
//
// Created by lgy on 2020-03-16.
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>

typedef struct {
    void (*task_cb)(void *arg);
    void *arg;
}st_task;

typedef struct {

    int max_tasks_cnt;
    int runing_tasks_cnt;
    st_task *tasks;
    int taskhead;
    int tasktail;

    pthread_t *threads;
    int threadcnt;

    int shutdown;
    pthread_mutex_t threadpool_lock;
    pthread_cond_t empty_task;//消耗任务条件变量
    pthread_cond_t set_task; //加任务条件变量
}st_threadpool;
st_threadpool *tp=NULL;

void *thread_cb(void *arg){
    while(1){
        st_task *task = (st_task*)malloc(sizeof(st_task));

        pthread_mutex_lock(&tp->threadpool_lock);
        while(!tp->shutdown && tp->runing_tasks_cnt <= 0){
            pthread_cond_wait(&tp->set_task,&tp->threadpool_lock);
        }
        if(tp->shutdown){
            pthread_mutex_unlock(&tp->threadpool_lock);
            free(task);
            pthread_exit(NULL);
        }
        if(tp->runing_tasks_cnt){
            //memcpy(task,&tp->tasks[tp->taskhead++%tp->max_tasks_cnt], sizeof(st_task));
            memcpy(task,&tp->tasks[tp->tasktail%tp->max_tasks_cnt],sizeof(st_task));
            tp->tasktail= (tp->tasktail+1)%tp->max_tasks_cnt;
            --(tp->runing_tasks_cnt);
            printf("tailpos:[%d] run_t:[%d]\n",tp->tasktail,tp->runing_tasks_cnt);
            pthread_cond_signal(&tp->empty_task);
        }
        pthread_mutex_unlock(&tp->threadpool_lock);
        task->task_cb(task->arg);
    }
}
void task_cb(void *){
    static int i =0;
    printf("this is task_cb() runing %d\n",i++);
}

void create_threadpool(int max_tasks_cnt,int threadcnt){
    tp = (st_threadpool *)malloc(sizeof(st_threadpool));

    tp->max_tasks_cnt=max_tasks_cnt;
    tp->runing_tasks_cnt=0;
    tp->tasks = (st_task *)malloc(sizeof(st_task)* max_tasks_cnt);
    tp->taskhead=0;
    tp->tasktail=0;

    tp->threadcnt=threadcnt;
    tp->threads = (pthread_t *)malloc(sizeof(pthread_t)*threadcnt);

    tp->shutdown=0;
    pthread_mutex_init(&tp->threadpool_lock,NULL);
    pthread_cond_init(&tp->empty_task,NULL);
    pthread_cond_init(&tp->set_task,NULL);

    for (int i = 0; i < threadcnt; ++i) {
        pthread_create(&tp->threads[i],NULL,thread_cb,tp);
        pthread_detach(tp->threads[i]);
    }

}
void add_task(){
    pthread_mutex_lock(&tp->threadpool_lock);
    while(tp->runing_tasks_cnt>=tp->max_tasks_cnt){
        pthread_cond_wait(&tp->empty_task,&tp->threadpool_lock);
    }
    tp->tasks[tp->taskhead].arg = (void*)&tp->tasks[tp->tasktail];
    tp->tasks[tp->taskhead].task_cb = task_cb;
    tp->taskhead = (tp->taskhead+1)%tp->max_tasks_cnt;
    ++(tp->runing_tasks_cnt);
    printf("headpos:[%d] run_t:[%d]\n",tp->taskhead,tp->runing_tasks_cnt);
    pthread_cond_signal(&tp->set_task);
    sleep(1);
    pthread_mutex_unlock(&tp->threadpool_lock);

}
void destroy_threadpool(){
    tp->shutdown=1;
    pthread_cond_broadcast(&tp->set_task);
    pthread_mutex_destroy(&tp->threadpool_lock);
    pthread_cond_destroy(&tp->set_task);
    pthread_cond_destroy(&tp->empty_task);
    free(tp->threads);
    free(tp->tasks);
    free(tp);
}

int main (){
    create_threadpool(10,4);
    for (int i = 0; i < 30; ++i) {
        add_task();
    }
    printf("end\n");
    sleep(100);
    //destroy_threadpool();
}

gcc threadpool.c -o tp -lpthread

伪代码:

数据结构:

  • 线程池:任务队列(循环队列),线程队列,shutdown标记,线程池锁,消费者条件变量,生产者条件变量。
  • 任务:执行函数,函数参数

逻辑

  • 初始化任务队列,线程数组,shutdown标记,线程池锁,消费者条件变量,生产者条件变量。创建线程(阻塞在生产者的条件变量)。
  • 线程池添加任务

    给线程池枷锁

    若任务队列为满,阻塞在消费者条件变量,直到消费者唤醒,重新执行这行逻辑。

    cpy任务队列的当前任务,调整任务队列,向生产者条件变量发送信号。

    线程池解锁

  • 线程执行

    被生产者唤醒,给线程池枷锁

    若shutdown!=1且任务队列为空,阻塞在生产者条件变量,直到被生产者唤醒,重新执行这行逻辑。

    任务队列去任务,调整任务队列,向消费者条件变量发送信号。

    线程池解锁

    执行任务

 

 

    

    

 

posted on 2020-03-17 16:24  lgy514  阅读(302)  评论(0编辑  收藏  举报