threadPool.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
const int NUMBER = 2;
typedef struct Task
{
void (*function)(void* arg);
void* arg;
}Task;
typedef struct ThreadPool
{
Task* taskQ;
int queueCapcity;//容量
int queueSize;//da'ang'qian
int queueFront;
int queueRear;
pthread_t managerID;
pthread_t *threadIDs;
int minNum;//最小线程数
int maxNum;//最大线程数
int busyNum;//忙的线程
int liveNum;//存活 线程数
int exitNum;//需要销毁的线程数
pthread_mutex_t mutexPool;
pthread_mutex_t mutexBusy;
int shutdown;//1是需要销毁,0就是不需要销毁
pthread_cond_t notFull;
pthread_cond_t notEmpty;
}ThreadPool;
//创建线程池并初始化
ThreadPool *threadPoolCreate(int min,int max,int queuesize);
void threadPoolAdd(ThreadPool* pool,void(*func)(void*),void*arg);
//获取线程中工作的线程个数
int threadPoolBusyNum(ThreadPool* pool);
//获取线程池中活着的线程个数
int threadPoolAliveNum(ThreadPool* pool);
int threadPoolDestroy(ThreadPool* pool);
void* worker(void * arg);
void* manager(void* arg);
void threadExit(ThreadPool *pool);
threadPool.cpp
#include "threadPool.h"
// 创建线程池
ThreadPool* threadPoolCreate(int min, int max, int queueSize) {
ThreadPool* pool = (ThreadPool*)malloc(sizeof(ThreadPool));
do {
if (pool == NULL) {
printf("create threadPool failed!\n");
break;
}
pool->threadIDs = (pthread_t*)malloc(sizeof(pthread_t) * max);
if (pool->threadIDs == NULL) {
printf("malloc threadIds failed!\n");
break;
}
memset(pool->threadIDs, 0, sizeof(pthread_t) * max);
pool->minNum = min;
pool->maxNum = max;
pool->busyNum = 0;
pool->liveNum = min;
pool->exitNum = 0;
if (pthread_mutex_init(&pool->mutexPool, NULL) != 0 ||
pthread_mutex_init(&pool->mutexBusy, NULL) != 0 ||
pthread_cond_init(&pool->notEmpty, NULL) != 0 ||
pthread_cond_init(&pool->notFull, NULL) != 0) {
printf("init mutex or cond failed!\n");
break;
}
pool->taskQ = (Task*)malloc(sizeof(Task) * queueSize);
pool->queueCapcity = queueSize;
pool->queueSize = 0;
pool->queueFront = 0;
pool->queueRear = 0;
pool->shutdown = 0;
pthread_create(&pool->managerID, NULL, manager, pool);
for (int i = 0; i < min; i++) {
pthread_create(&pool->threadIDs[i], NULL, worker, pool);
}
return pool;
} while (0);
if (pool->threadIDs) free(pool->threadIDs);
if (pool->taskQ) free(pool->taskQ);
if (pool) free(pool);
return NULL;
}
void threadPoolAdd(ThreadPool* pool, void(*func)(void*), void* arg) {
pthread_mutex_lock(&pool->mutexPool);
while (pool->queueSize == pool->queueCapcity && !pool->shutdown) {
pthread_cond_wait(&pool->notFull, &pool->mutexPool);
}
if (pool->shutdown) {
pthread_mutex_unlock(&pool->mutexPool);
return;
}
pool->taskQ[pool->queueRear].function = func;
pool->taskQ[pool->queueRear].arg = arg;
pool->queueRear = (pool->queueRear + 1) % pool->queueCapcity;
pool->queueSize++;
pthread_cond_signal(&pool->notEmpty);
pthread_mutex_unlock(&pool->mutexPool);
}
int threadPoolBusyNum(ThreadPool* pool) {
pthread_mutex_lock(&pool->mutexBusy);
int busyNum = pool->busyNum;
pthread_mutex_unlock(&pool->mutexBusy);
return busyNum;
}
int threadPoolAliveNum(ThreadPool* pool) {
pthread_mutex_lock(&pool->mutexPool);
int aliveNum = pool->liveNum;
pthread_mutex_unlock(&pool->mutexPool);
return aliveNum;
}
int threadPoolDestroy(ThreadPool* pool) {
if (pool == NULL) return -1;
pool->shutdown = 1;
pthread_join(pool->managerID, NULL);
for (int i = 0; i < pool->liveNum; i++) {
pthread_cond_signal(&pool->notEmpty);
}
if (pool->threadIDs) free(pool->threadIDs);
if (pool->taskQ) free(pool->taskQ);
pthread_mutex_destroy(&pool->mutexPool);
pthread_mutex_destroy(&pool->mutexBusy);
pthread_cond_destroy(&pool->notEmpty);
pthread_cond_destroy(&pool->notFull);
free(pool);
pool = NULL;
return 0;
}
void* worker(void* arg) {
ThreadPool* pool = (ThreadPool*)arg;
while (1) {
pthread_mutex_lock(&pool->mutexPool);
while (pool->queueSize == 0 && !pool->shutdown) {
pthread_cond_wait(&pool->notEmpty, &pool->mutexPool);
if (pool->exitNum > 0) {
pool->exitNum--;
if (pool->liveNum > pool->minNum) {
pool->liveNum--;
pthread_mutex_unlock(&pool->mutexPool);
threadExit(pool);
}
}
}
if (pool->shutdown) {
pthread_mutex_unlock(&pool->mutexPool);
threadExit(pool);
}
Task task;
task.function = pool->taskQ[pool->queueFront].function;
task.arg = pool->taskQ[pool->queueFront].arg;
pool->queueFront = (pool->queueFront + 1) % pool->queueCapcity;
pool->queueSize--;
pthread_cond_signal(&pool->notFull);
pthread_mutex_unlock(&pool->mutexPool);
printf("thread %ld begin working!\n", pthread_self());
pthread_mutex_lock(&pool->mutexBusy);
pool->busyNum++;
pthread_mutex_unlock(&pool->mutexBusy);
task.function(task.arg);
free(task.arg);
task.arg = NULL;
printf("thread %ld end working!\n", pthread_self());
pthread_mutex_lock(&pool->mutexBusy);
pool->busyNum--;
pthread_mutex_unlock(&pool->mutexBusy);
}
return NULL;
}
void* manager(void* arg) {
ThreadPool* pool = (ThreadPool*)arg;
while (!pool->shutdown) {
sleep(3);
pthread_mutex_lock(&pool->mutexPool);
int queueSize = pool->queueSize;
int liveNum = pool->liveNum;
pthread_mutex_unlock(&pool->mutexPool);
pthread_mutex_lock(&pool->mutexBusy);
int busyNum = pool->busyNum;
pthread_mutex_unlock(&pool->mutexBusy);
if (queueSize > liveNum && liveNum < pool->maxNum) {
pthread_mutex_lock(&pool->mutexPool);
int counter = 0;
for (int i = 0; i < pool->maxNum && counter < NUMBER && pool->liveNum < pool->maxNum; i++) {
if (pool->threadIDs[i] == 0) {
pthread_create(&pool->threadIDs[i], NULL, worker, pool);
counter++;
pool->liveNum++;
}
}
pthread_mutex_unlock(&pool->mutexPool);
}
if (busyNum * 2 < liveNum && liveNum > pool->minNum) {
pthread_mutex_lock(&pool->mutexPool);
pool->exitNum = NUMBER;
pthread_mutex_unlock(&pool->mutexPool);
for (int i = 0; i < NUMBER; i++) {
pthread_cond_signal(&pool->notEmpty);
}
}
}
return NULL;
}
void threadExit(ThreadPool* pool) {
pthread_t tid = pthread_self();
for (int i = 0; i < pool->maxNum; i++) {
if (pool->threadIDs[i] == tid) {
pool->threadIDs[i] = 0;
printf("function threadExit, %ld thread exiting!\n", tid);
break;
}
}
pthread_exit(NULL);
}
main.cpp
#include"threadPool.h"
#include<iostream>
void taskFunc(void *arg) {
int num = *(int*)arg;
while (1) {
printf("thread is working,number= %d ,tid=%ld \n", num++, pthread_self());
sleep(2);
}
}
void taskFunc1(void* arg) {
int num = *(int*)arg;
while (1) {
printf("thread is working,number= %d ,tid=%ld \n", num++, pthread_self());
sleep(2);
}
}
int main() {
ThreadPool* pool=threadPoolCreate(3,10,100);
int* num = (int*)malloc(sizeof(int));
*num =111;
threadPoolAdd(pool,taskFunc,num);
int* num1 = (int*)malloc(sizeof(int));
*num1 = 222;
threadPoolAdd(pool, taskFunc1, num1);
int mainNum = 0;
while (1) {
printf("main is working,number= %d ,tid=%ld \n", mainNum++, pthread_self());
sleep(2);
}
threadPoolDestroy(pool);
return 0;
}