线程池有很多种不同的理解认识,自己总结是一种方式
主要目的:并行处理,加快程序处理速度
比如一张图片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;
}