自己实现的一种简单线程池

线程池有很多种不同的理解认识,自己总结是一种方式

主要目的:并行处理,加快程序处理速度

比如一张图片40MB,需要对图片进行处理,可以分成4份,分配给4个线程分别处理,同一时间4份同时处理完成了

但是实际运行场景会有各式各样的情况,就需要对不同场景,进行调整适配了

具体线程数并不是越多越好,是有一个限定最事宜的

实现的方式:是通过链表将数据关联起来,从头部插入数据,线程从尾部进行取出数据的思路,这样的目的是可以将最早的数据进行先行处理了

只是一个雏形,还需要很多改进

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

/*
*@author: 赵秋然
*@date:2021年2月2日
*@description:线程池
*/

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
typedef struct taskv
{
    struct taskv *front;
    struct taskv *next;
    struct taskv *tail;
    int task_count;
    void *value;
    void *(*task_run)(void *arg);
} task_info;

typedef struct tasket
{
    task_info *head;
    pthread_cond_t *cval;
    pthread_mutex_t *mtx;
    int thread_num;
    pthread_t *tid;
} tasket_c;

///头部插入数据
#define TASK_ADD(task,head) \
    do{\
        if(head == NULL)\
        {\
            head = task;\
            head->task_count = 1;\
            break;\
        }\
        task->next = head;\
        task->tail = head->tail;\
        head->tail= NULL;\
        head->front = task;\
        head = task;\
        head->task_count = ++task->next->task_count;\
        task->next->task_count = 0;\
        break;\
    } while (1);


///尾部获取并删除数据
#define TASK_GET(cur,head) \
    do{\
        if(head == NULL) \
        {\
            *cur = NULL;\
            break ;\
        } \
        \
        head->task_count--;\
        *cur = head->tail; \
        if(head->tail == head) \
        {\
            *cur = head;\
            break ;\
        }\
        \
        head->tail = *cur->front;\
        head->tail->next = NULL;\
        break;\
    }while(1)


int   run = 1;
void *work_run(void *arg)
{
    int *va = (int *)arg;
    printf(" work_run thread_id [%d] , value [%d] \n", pthread_self(), *va);
    if (va)
    {
        free(va);
    }

    sleep(1);
}

void *start_routine(void *arg)
{
    tasket_c *thread_task = (tasket_c *)arg;
    task_info *tamp = NULL;
    while (run)
    {
        pthread_mutex_lock(thread_task->mtx);
        while ((thread_task->head == NULL) || (run && thread_task->head->task_count <= 0))
        {
            pthread_cond_wait(thread_task->cval, thread_task->mtx);
        }

        if (!run)
        {
            pthread_mutex_unlock(thread_task->mtx);
            break;
        }

        TASK_GET(&tamp, thread_task->head);
        pthread_mutex_unlock(thread_task->mtx);
        tamp->task_run(tamp->value);
        if (tamp)
        {
            free(tamp);
            tamp = NULL;
        }
    }

    printf("release thread_id [%d] \n", pthread_self());
    return 0;
}

void create_thread_pool(tasket_c *taskc)
{
    taskc->tid  = (pthread_t *)calloc(taskc->thread_num, sizeof(pthread_t));
    if (taskc->tid == NULL)
    {
        printf("calloc failed \n");
        return;
    }

    taskc->cval = &cond;
    taskc->mtx = &mutex;

    int i = 0;
    for (i = 0 ; i < taskc->thread_num ; ++i)
    {
        if (pthread_create(&taskc->tid[i], NULL, start_routine,  taskc) != 0)
        {
            printf(" %d pthread_create failed \n", i);
            return ;
        }
    }

}

void release_thread_pool(tasket_c *taskc)
{
    int i = 0;
    run = 0;
    pthread_cond_broadcast(taskc->cval);
    for (i = 0 ; i < taskc->thread_num ; ++i)
    {
        pthread_join(taskc->tid[i], NULL);
    }

    if (taskc->tid)
    {
        free(taskc->tid);
        taskc->tid = NULL;
    }
}

void add_renwu(tasket_c *taskc)
{
    task_info *task_tmp = NULL;
    int i = 0;
    for (i = 0; i < 10; ++i)
    {
        task_tmp = (task_info *)calloc(1, sizeof(task_info));
        task_tmp->value = (void *)calloc(1, sizeof(int));
        *(int *)task_tmp->value = i;
        task_tmp->tail = task_tmp;
        task_tmp->task_run = work_run;
        TASK_ADD(task_tmp, taskc->head);
    }
}

int main()
{
    tasket_c taskc;
    memset(&taskc, '\0', sizeof(taskc));
    taskc.thread_num = 3;
    create_thread_pool(&taskc);
    printf("create thread succe !\n");
    sleep(3);
    add_renwu(&taskc);
    pthread_cond_broadcast(taskc.cval);

    printf("succ task_count [%d]\n", taskc.head->task_count);
    sleep(4);
    release_thread_pool(&taskc);
    printf("fin succ \n");
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值