什么是线程池
线程池就是一个拥有多个线程的池子,它是多线程的一种使用方式,可以将他理解为一个执行队列,我们只需将需要完成的
工作或任务丢到线程池的工作队列中,由线程池中的线程来抢夺工作队列中的任务即可,没有抢到任务的线程处于休眠状态。
如何实现线程池
在线程池中主要可分为两大结构体,或是两个主要对象,那就是工作队列和执行队列,工作队列中保存我们待执行的任务,
执行队列就是一个一个的线程。两个结构体如下:
工作队列
struct queue_jobs
{
struct queue_jobs *prev;
struct queue_jobs *next;
pthread_work_cb work_cb;
void *arg;
};
执行队列
struct pthread_pool
{
int pth_num_max;
pthread_t *tid;
pthread_cond_t pth_cond;
pthread_mutex_t pth_mutex;
};
其中工作队列为一个双向链表构成,结构体成员pthread_work_cb work_cb为一个函数指针,指向具体的回调函数;执行队列就是我们的线程池,主要的两个成员变量pthread_cond_t pth_cond、pthread_mutex_t pth_mutex用于操作工作队列时需要加锁,同时通知执行队列当前是否有需要执行的工作,也就是当我们向工作队列添加一个任务时,会发送一个信号来通知执行队列,执行队列收到信号后会去工作队列取出任务来执行。
完整代码如下:
pthread_pool.h
#ifndef PTHREAD_H_
#define PTHREAD_H_
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct pthread_pool pth_pool_t;
typedef void *(*pthread_work_cb)(void *);
typedef struct queue_jobs queue_jobs_t;
struct pthread_pool
{
int pth_num_max;
pthread_t *tid;
pthread_cond_t pth_cond;
pthread_mutex_t pth_mutex;
};
struct queue_jobs
{
struct queue_jobs *prev;
struct queue_jobs *next;
pthread_work_cb work_cb;
void *arg;
};
enum{
OK = 0,
POINTER_NULL = -1,
};
int pthread_pool_init(pth_pool_t **pool,int pth_num);
void pthread_pool_add_task(pthread_work_cb task,void *arg);
void pthread_pool_destroy(pth_pool_t * pth_pool);
#endif
pthread_pool.c
#include "pthread_pool.h"
pth_pool_t *pth_pool;
queue_jobs_t *q_jobs = NULL;
void *pthread_routine(void *arg);
int pthread_pool_init(pth_pool_t **pool,int pth_num)
{
*pool = (pth_pool_t*)malloc(sizeof(pth_pool_t));
if (*pool == NULL)
return POINTER_NULL;
(*pool)->pth_num_max = pth_num;
(*pool)->tid = (pthread_t*)malloc(sizeof(pthread_t) * pth_num);
pthread_mutex_init(&((*pool)->pth_mutex),NULL);
pthread_cond_init(&((*pool)->pth_cond),NULL);
for(int i=0;i<pth_num;i++)
pthread_create(&((*pool)->tid[i]),NULL,pthread_routine,NULL);
return OK;
}
void pthread_pool_add_task(pthread_work_cb task,void *arg)
{
if(task == NULL)
return;
queue_jobs_t *job = (queue_jobs_t*)malloc(sizeof(queue_jobs_t));
if(job == NULL)
return ;
job->work_cb = task;
job->arg = arg;
pthread_mutex_lock(&(pth_pool->pth_mutex));
if(q_jobs == NULL)
q_jobs = job;
else
{
job->next = q_jobs;
q_jobs->prev = job;
q_jobs = job;
}
pthread_mutex_unlock(&(pth_pool->pth_mutex));
pthread_cond_signal(&(pth_pool->pth_cond));
}
void *pthread_routine(void *arg)
{
queue_jobs_t *job;
pthread_detach(pthread_self());
while(1)
{
#if 1
pthread_mutex_lock(&(pth_pool->pth_mutex));
while(q_jobs == NULL)
pthread_cond_wait(&(pth_pool->pth_cond),&(pth_pool->pth_mutex));
job =q_jobs;
q_jobs = q_jobs->next;
pthread_mutex_unlock(&(pth_pool->pth_mutex));
job->work_cb(job->arg);
free(job);
job = NULL;
#endif
}
pthread_exit(NULL);
}
void pthread_pool_destroy(pth_pool_t * pth_pool)
{
queue_jobs_t *job;
if(pth_pool == NULL)
return ;
pthread_mutex_destroy(&pth_pool->pth_mutex);
pthread_cond_destroy(&pth_pool->pth_cond);
while(q_jobs)
{
job = q_jobs;
q_jobs = q_jobs->next;
free(job);
}
free(pth_pool->tid);
free(pth_pool);
}
测试main.c,这里我创建了一个线程池,里面有8个线程,同时向线程池中添加了8个任务,每个任务执行的时间不同。
#include <unistd.h>
#include <stdio.h>
#include "pthread_pool.h"
#define PTHREAD_NUM_MAX 8
extern pth_pool_t *pth_pool;
void * pthread1_task(void *arg)
{
for (int i = 0; i < 3; i++)
{
/* code */
printf("this is 1 thread,tid:%ld\n",pthread_self());
sleep(1);
}
return (void *)0;
}
void * pthread2_task(void *arg)
{
for (int i = 0; i < 4; i++)
{
/* code */
printf("this is 2 thread,tid:%ld\n",pthread_self());
sleep(1);
}
return (void *)0;
}
void * pthread3_task(void *arg)
{
for (int i = 0; i < 5; i++)
{
/* code */
printf("this is 3 thread,tid:%ld\n",pthread_self());
sleep(1);
}
return (void *)0;
}
void * pthread4_task(void *arg)
{
for (int i = 0; i < 6; i++)
{
/* code */
printf("this is 4 thread,tid:%ld\n",pthread_self());
sleep(1);
}
return (void *)0;
}
void * pthread5_task(void *arg)
{
for (int i = 0; i < 6; i++)
{
/* code */
printf("this is 5 thread,tid:%ld\n",pthread_self());
sleep(1);
}
return (void *)0;
}
void * pthread6_task(void *arg)
{
for (int i = 0; i < 6; i++)
{
/* code */
printf("this is 6 thread,tid:%ld\n",pthread_self());
sleep(1);
}
return (void *)0;
}
void * pthread7_task(void *arg)
{
for (int i = 0; i < 2; i++)
{
/* code */
printf("this is 7 thread,tid:%ld\n",pthread_self());
sleep(1);
}
return (void *)0;
}
void * pthread8_task(void *arg)
{
for (int i = 0; i < 1; i++)
{
/* code */
printf("this is 8 thread,tid:%ld\n",pthread_self());
sleep(1);
}
return (void *)0;![在这里插入图片描述](https://img-blog.csdnimg.cn/babbfbae42014a1cbc4585d30a24106d.png#pic_center)
}
int main()
{
if(pthread_pool_init(&pth_pool,PTHREAD_NUM_MAX) == 0)
printf("pthread pool init success\n");
else
{
printf("pthread pool init failed\n");
return -1;
}
pthread_pool_add_task(pthread1_task,NULL);
pthread_pool_add_task(pthread2_task,NULL);
pthread_pool_add_task(pthread3_task,NULL);
pthread_pool_add_task(pthread4_task,NULL);
pthread_pool_add_task(pthread5_task,NULL);
pthread_pool_add_task(pthread6_task,NULL);
pthread_pool_add_task(pthread7_task,NULL);
pthread_pool_add_task(pthread8_task,NULL);
while(1);
return 0;
}
执行效果:
到此完结!