参考网络代码后加上自己理解后的手写记录
头文件
//
// Created by zl on 2020-03-13.
//
#ifndef LINUX_THREADPOOL_H
#define LINUX_THREADPOOL_H
#include
#include
#include
#include
// 线程池运行状态的枚举值
typedef enum threadPoolFlag{RUN=0,END=1}TPF;
// 任务节点队列结构体
typedef struct _TAQ{
void* (*fun)(void*); // 指向函数的指针,函数返回void*类型指针,参数是void类型指针
void*argv; //任务函数的参数
struct _TAQ*next;
}TAQ;
// 线程池结构体
typedef struct _threadPool {
TPF flag;//线程池运行的标志,是否运行停止
TAQ *taskHead; // 任务队列头指针
pthread_cond_t taskCond; // 任务条件变量
pthread_mutex_t taskMutex; // 任务互斥锁
pthread_t *threadID; // 线程id号数组头指针
int maxThreadNum; // 最大线程数
int curThreadNum; // 线程池中当前活跃的线程数
int curTaskNum; // 当前任务数
}THP;
static THP *threadPool =NULL;
THP*createThreadPool(int threadNum);// 创建线程池
void*threadHandle(void* argv); // 处理线程函数
void addTask(void* (*fun)(void*),void* argv); //向任务队列中添加任务
void destroyThreadPool();
#endif //LINUX_THREADPOOL_H
实体和测试文件
//
// Created by zl on 2020-03-13.
//
#include <zconf.h>
#include "threadPool.h"
//创建线程池
THP* createThreadPool(int threadNum) {
threadPool = (THP*) malloc(sizeof(THP));
threadPool->flag = RUN;
threadPool->maxThreadNum = threadNum;
pthread_mutex_init(&(threadPool->taskMutex),NULL);
pthread_cond_init(&(threadPool->taskCond),NULL);
threadPool->curTaskNum = 0;
threadPool->curThreadNum = 0;
//分配线程id数组空间
threadPool->threadID = (pthread_t*)malloc(threadNum* sizeof(pthread_t));
int i=0;
for (;i<threadNum;i++) { //创建线程
pthread_create(&(threadPool->threadID[i]),NULL,threadHandle,NULL);
}
return threadPool;
}
// 增加任务到任务队列
void addTask(void* (*fun)(void*),void* argv) {
// 新来的任务添加到任务队列头部
TAQ *newTask = (TAQ*)malloc(sizeof(TAQ));
newTask->fun = fun;
newTask->argv = argv;
// 任务队列数原子性的添加
pthread_mutex_lock(&(threadPool->taskMutex));
newTask->next = threadPool->taskHead;
threadPool->taskHead = newTask;
++threadPool->curTaskNum;
// 如果线程池中还有线程,就唤醒其中一个线程去执行任务
if (threadPool->curThreadNum < threadPool->maxThreadNum) {
pthread_cond_signal(&(threadPool->taskCond));
}
pthread_mutex_unlock(&(threadPool->taskMutex));
}
// 线程处理函数
void* threadHandle(void* argv) {
while (threadPool->flag==RUN) {
pthread_mutex_lock(&(threadPool->taskMutex));
while (threadPool->flag == RUN && threadPool->curTaskNum == 0) { //没有任务等待添加任务
pthread_cond_wait(&(threadPool->taskCond),&(threadPool->taskMutex));
}
// 执行任务队列中的任务
if (threadPool->flag == RUN) {
TAQ *p = threadPool->taskHead; //领取任务
threadPool->taskHead = threadPool->taskHead->next;
--threadPool->curTaskNum; //任务数减1
++threadPool->curThreadNum;//活跃线程数+1
pthread_mutex_unlock(&(threadPool->taskMutex));
//执行任务
(*(p->fun))(p->argv);
free(p);
p = NULL;
--threadPool->curThreadNum;
} else if(threadPool->flag == END) { //销毁线程池
--threadPool->maxThreadNum;
pthread_mutex_unlock(&(threadPool->taskMutex));
pthread_detach(pthread_self());
pthread_exit(NULL);
}
}
}
//销毁线程池
void destroyThreadPool() {
if (threadPool->flag == RUN) {
threadPool->flag = END;
pthread_cond_broadcast(&(threadPool->taskCond));
TAQ *p = threadPool->taskHead;
while (p) {
--threadPool->curTaskNum;
threadPool->taskHead = threadPool->taskHead->next;
free(p);
p = threadPool->taskHead;
}
}
}
void* testFun(void* argv) {
int *p= (int*)argv;
printf("线程号%lu:开始执行函数。argv=%d\n",pthread_self(),*p);
sleep(1);
printf("线程号%lu:函数执行完毕!argv=%d\n",pthread_self(),*p);
return NULL;
}
int main() {
THP *thp=createThreadPool(3);
int i=0;
for(;i<20;++i)
{
addTask(testFun,(void*)(&i));
sleep(1);
}
while(thp->curTaskNum!=0);
printf("任务执行完毕\n");
destroyThreadPool();
return 0;
}
测试结果
![](https://img.haomeiwen.com/i6573910/f113a0030c2fa210.png)
可见一直是创建的三个线程在处理任务
网友评论