简单介绍
我们写的线程池中预计最多会有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;
}
代码运行结果
如果代码或者文章中有什么错误,欢迎指出。