手写线程池

简单介绍

我们写的线程池中预计最多会有8个线程在同时工作。
这8个线程会组成一个工作队列(队列使用双向链表进行实现)。
需要我们去处理的任务量暂定为2000条。
这2000条任务会依次存储到一个任务队列中(队列使用双向链表进行实现)。
工作内容为将自身的ID给输出到屏幕上。
每个线程会先判断任务队列中有没有任务需要去处理,如果有的话就去调用任务函数去处理任务
任务全部处理完成后将相关的资源进行释放

代码

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define COUNT_TASKS 2000
#define COUNT_WORKERS 1

//双向链表的插入,头插法
#define LIST_INSERT(item,list) do \
{                                 \
    if (list == NULL){            \
        list = item;              \
        list->next = NULL;        \
        list->pre = NULL;         \
    }                             \
    else{                         \
        item->next = list;        \
        list->pre = item;         \
        list = item;              \
        list->pre = NULL;         \
    }                             \
} while (0);                      

//双向链表 删除头节点
#define LIST_REMOVE(list) do     \
{                                \
    if(list == NULL);            \
    else{                        \
        list = list->next;       \
        if(list != NULL)         \
        list ->pre = NULL;       \
    }                            \
} while (0);                     


//任务队列中的任务函数
void function_task(int id){
    printf("The id of task is %d\n",id);
}
//任务队列
struct Task
{
    //ID
    int id;
    //前驱节点
    struct Task *pre;  
    //后继节点
    struct Task *next;
    //任务函数
    void (*function_task)(int id);
};

//工作队列
struct Work
{
    //进程ID
    pthread_t thread_id;
    //前驱节点
    struct Work *pre;
    //后继
    struct Work *next;
    //进程结束标志 0位正常 1为结束
    int terminal_tag;
};

//线程池
struct  ThreadPool
{
    //工作队列
    struct Work *works;
    //任务队列
    struct Task *tasks;
    //互斥锁
    pthread_mutex_t mutex;
    //条件变量
    pthread_cond_t cond;
};

//每个线程的回调函数
void *call_back(void *arg){
    struct ThreadPool *thread_pool = (struct ThreadPool *)arg;
    while (1)
    {
        //上锁
        int res = pthread_mutex_lock(&thread_pool->mutex);
        if (res)
        {
            perror("pthread_mutex_lock\n");
        }

        //debug
        // if (thread_pool->tasks == NULL)
        // {
        //     printf("wait before\n");
        // }

        while(thread_pool->tasks == NULL)
        {
            int res = pthread_cond_wait(&thread_pool->cond,&thread_pool->mutex);
            // printf("%d\n",res);
            if (res)
            {
                perror("pthread_mutex_lock\n");
            }
            if (thread_pool->works->terminal_tag == 1)
            break;
        }

        if (thread_pool->works->terminal_tag == 1)
        break; 

        //debug
        // if (thread_pool->tasks == NULL)
        // {
        //     printf("remove before\n");
        // }

        //任务队列不为空
        struct Task *task = thread_pool->tasks;
        LIST_REMOVE(thread_pool->tasks);

        //debug
        // if (thread_pool->tasks == NULL)
        // {
        //     printf("over\n");
        // }
        
        //执行任务
        task->function_task(task->id);
        // printf("helloha\n");

        //解锁
        res = pthread_mutex_unlock(&thread_pool->mutex);
        if (res)
        {
            perror("pthread_mutex_lock\n");
        }

        free(task);
    }
}

//推送任务
int task_push(struct Task *task,struct ThreadPool *thread_pool){
    //上锁
    int res = pthread_mutex_lock(&thread_pool->mutex);
    if (res)
    {
        perror("pthread_mutex_lock\n");
        return -1;
    }
    // printf("hello\n");
    LIST_INSERT(task,thread_pool->tasks);
    // printf("hello\n");
    pthread_cond_signal(&thread_pool->cond);
    //解锁
    res = pthread_mutex_unlock(&thread_pool->mutex);
    if (res)
    {
        perror("pthread_mutex_unlock\n");
        return -2;
    }
    //   printf("hello\n");

    return 0;
}

//线程池初始化
int thread_pool_initial(struct ThreadPool *thread_pool){

    int res = pthread_mutex_init(&thread_pool->mutex,NULL);
    if (res)
    {
        perror("pthread_mutex_init\n");
        return -1;
    }
    res = pthread_cond_init(&thread_pool->cond,NULL);
    if (res)
    {
        perror("pthread_cond_init\n");
        return -2;
    }

    thread_pool->tasks = NULL;
    thread_pool->works = NULL;

    for (int i = 0; i < COUNT_WORKERS; i++)
    {
        struct Work *work = (struct Work*)malloc(sizeof(struct Work));
        work->terminal_tag = 0;
        res = pthread_create(&work->thread_id,NULL,call_back,thread_pool);
        if (res)
        {
            perror("pthread_creat\n");
            return -2;
        }
        
        LIST_INSERT(work,thread_pool->works);
    }

    for (int i = 1; i <= COUNT_TASKS; i++)
    {
        // printf("%d\n",i);
        struct Task *task = (struct Task*)malloc(sizeof(struct Task));
        if (task == NULL)
        {
            perror("malloc\n");
            return -1;
        }
        task->id = i;
        task->function_task = function_task;
        task_push(task,thread_pool);
        
        // printf("%d\n",i);
    }

    return 0;
}

int thread_pool_destroy(struct ThreadPool *thread_pool){
    struct Work *work = (struct Work*)malloc(sizeof(struct Work));
    while (1)
    {
        //上锁
        int res = pthread_mutex_lock(&thread_pool->mutex);
        if (res)
        {
            perror("pthread_mutex_lock\n");
            return -1;
        }

        if (thread_pool->tasks == NULL)
        {
            for (int i = 0; i < COUNT_WORKERS; i++)
            {
                work = thread_pool->works;
                work->terminal_tag = 1;
                work = work->next;
            }
            res = pthread_cond_broadcast(&thread_pool->cond);
            if (res)
            {
                perror("pthread_cond\n");
                return -2;
            }
             //解锁
            res = pthread_mutex_unlock(&thread_pool->mutex);
            break;
        }

        //解锁
        res = pthread_mutex_unlock(&thread_pool->mutex);
        if (res)
        {
            perror("pthread_mutex_lock\n");
            return -2;
        }
    }
        //等待线程结束
        for (int i = 0; i < COUNT_WORKERS; i++)
        {
            work = thread_pool->works;
            if(pthread_join(work->thread_id,NULL))
            printf("pthread_join error\n");
            LIST_REMOVE(thread_pool->works);
            free(work);
        }
    

    return 0;
}


int main(){
    struct ThreadPool *thread_pool = (struct ThreadPool*)malloc(sizeof(struct ThreadPool));
    thread_pool_initial(thread_pool);
    thread_pool_destroy(thread_pool);
    // getchar();
    return 0;
}

代码运行结果

在这里插入图片描述

如果代码或者文章中有什么错误,欢迎指出。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值