#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include<vector>
#include<iostream>
const int NUMBER = 2;
typedef struct Task {
void (*function)(void* arg);
void* arg;
} Task;
typedef struct ThreadPool {
Task* taskQ;
int queueCapacity; // 容量
int queueSize; // 当前大小
int queueFront;
int queueRear;
HANDLE managerID;
HANDLE* threadIDs;
int minNum; // 最小线程数
int maxNum; // 最大线程数
int busyNum; // 忙的线程数
int liveNum; // 存活线程数
int exitNum; // 需要销毁的线程数
CRITICAL_SECTION mutexPool;
CRITICAL_SECTION mutexBusy;
int shutdown; // 1是需要销毁,0是不需要销毁
CONDITION_VARIABLE notFull;
CONDITION_VARIABLE 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);
DWORD WINAPI worker(LPVOID arg);
DWORD WINAPI manager(LPVOID arg);
void threadExit(ThreadPool* pool);
// 线程池的实现
ThreadPool* threadPoolCreate(int min, int max, int queueSize) {
ThreadPool* pool = (ThreadPool*)malloc(sizeof(ThreadPool));
if (pool == NULL) {
printf("malloc threadPool fail...\n");
return NULL;
}
pool->taskQ = (Task*)malloc(sizeof(Task) * queueSize);
pool->queueCapacity = queueSize;
pool->queueSize = 0;
pool->queueFront = 0;
pool->queueRear = 0;
pool->minNum = min;
pool->maxNum = max;
pool->busyNum = 0;
pool->liveNum = min;
pool->exitNum = 0;
pool->shutdown = 0;
InitializeCriticalSection(&pool->mutexPool);
InitializeCriticalSection(&pool->mutexBusy);
InitializeConditionVariable(&pool->notFull);
InitializeConditionVariable(&pool->notEmpty);
pool->threadIDs = (HANDLE*)malloc(sizeof(HANDLE) * max);
for (int i = 0; i < min; ++i) {
pool->threadIDs[i] = CreateThread(NULL, 0, worker, pool, 0, NULL);
}
pool->managerID = CreateThread(NULL, 0, manager, pool, 0, NULL);
return pool;
}
void threadPoolAdd(ThreadPool* pool, void(*func)(void*), void* arg) {
EnterCriticalSection(&pool->mutexPool);
while (pool->queueSize == pool->queueCapacity && !pool->shutdown) {
SleepConditionVariableCS(&pool->notFull, &pool->mutexPool, INFINITE);
}
if (pool->shutdown) {
LeaveCriticalSection(&pool->mutexPool);
return;
}
pool->taskQ[pool->queueRear].function = func;
pool->taskQ[pool->queueRear].arg = arg;
pool->queueRear = (pool->queueRear + 1) % pool->queueCapacity;
pool->queueSize++;
WakeConditionVariable(&pool->notEmpty);
LeaveCriticalSection(&pool->mutexPool);
}
int threadPoolBusyNum(ThreadPool* pool) {
EnterCriticalSection(&pool->mutexBusy);
int busyNum = pool->busyNum;
LeaveCriticalSection(&pool->mutexBusy);
return busyNum;
}
int threadPoolAliveNum(ThreadPool* pool) {
EnterCriticalSection(&pool->mutexPool);
int liveNum = pool->liveNum;
LeaveCriticalSection(&pool->mutexPool);
return liveNum;
}
int threadPoolDestroy(ThreadPool* pool) {
if (pool == NULL) {
return -1;
}
pool->shutdown = 1;
WakeAllConditionVariable(&pool->notEmpty);
WaitForSingleObject(pool->managerID, INFINITE);
for (int i = 0; i < pool->liveNum; ++i) {
WakeAllConditionVariable(&pool->notEmpty);
}
for (int i = 0; i < pool->maxNum; ++i) {
if (pool->threadIDs[i] != NULL) {
WaitForSingleObject(pool->threadIDs[i], INFINITE);
CloseHandle(pool->threadIDs[i]);
}
}
free(pool->taskQ);
free(pool->threadIDs);
DeleteCriticalSection(&pool->mutexPool);
DeleteCriticalSection(&pool->mutexBusy);
free(pool);
return 0;
}
DWORD WINAPI worker(LPVOID arg) {
ThreadPool* pool = (ThreadPool*)arg;
while (1) {
EnterCriticalSection(&pool->mutexPool);
while (pool->queueSize == 0 && !pool->shutdown) {
SleepConditionVariableCS(&pool->notEmpty, &pool->mutexPool, INFINITE);
}
if (pool->shutdown) {
LeaveCriticalSection(&pool->mutexPool);
threadExit(pool);
}
Task task = pool->taskQ[pool->queueFront];
pool->queueFront = (pool->queueFront + 1) % pool->queueCapacity;
pool->queueSize--;
WakeConditionVariable(&pool->notFull);
LeaveCriticalSection(&pool->mutexPool);
EnterCriticalSection(&pool->mutexBusy);
pool->busyNum++;
LeaveCriticalSection(&pool->mutexBusy);
task.function(task.arg);
EnterCriticalSection(&pool->mutexBusy);
pool->busyNum--;
LeaveCriticalSection(&pool->mutexBusy);
}
return 0;
}
DWORD WINAPI manager(LPVOID arg) {
ThreadPool* pool = (ThreadPool*)arg;
while (!pool->shutdown) {
Sleep(3 * 1000);
EnterCriticalSection(&pool->mutexPool);
int queueSize = pool->queueSize;
int liveNum = pool->liveNum;
LeaveCriticalSection(&pool->mutexPool);
EnterCriticalSection(&pool->mutexBusy);
int busyNum = pool->busyNum;
LeaveCriticalSection(&pool->mutexBusy);
if (queueSize > liveNum && liveNum < pool->maxNum) {
EnterCriticalSection(&pool->mutexPool);
int counter = 0;
for (int i = 0; i < pool->maxNum && counter < NUMBER && pool->liveNum < pool->maxNum; ++i) {
if (pool->threadIDs[i] == NULL || WaitForSingleObject(pool->threadIDs[i], 0) == WAIT_OBJECT_0) {
pool->threadIDs[i] = CreateThread(NULL, 0, worker, pool, 0, NULL);
counter++;
pool->liveNum++;
}
}
LeaveCriticalSection(&pool->mutexPool);
}
if (busyNum * 2 < liveNum && liveNum > pool->minNum) {
EnterCriticalSection(&pool->mutexPool);
pool->exitNum = NUMBER;
LeaveCriticalSection(&pool->mutexPool);
for (int i = 0; i < NUMBER; ++i) {
WakeConditionVariable(&pool->notEmpty);
}
}
}
return 0;
}
void threadExit(ThreadPool* pool) {
EnterCriticalSection(&pool->mutexPool);
pool->liveNum--;
LeaveCriticalSection(&pool->mutexPool);
ExitThread(0);
}
std::vector<int>taskVec = {11,11,11,11};
void taskFunc(void* arg) {
for (int i = 0; i < 100000;i++) {
taskVec.push_back(i);
std::cout << "push back size: " << taskVec.size() << std::endl;
std::cout << "push back last value: " << taskVec[taskVec.size()-1] << std::endl;
Sleep(1000);
}
}
void taskFunc1(void* arg) {
for (int i = 0; i < 100000; i++) {
taskVec.pop_back();
std::cout << "pop back size: " << taskVec.size() << std::endl;
std::cout << "pop back last value: " << taskVec[taskVec.size() - 1] << std::endl;
Sleep(1000);
}
}
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) {
}
threadPoolDestroy(pool);
return 0;
}
Widnows 平台线程池
最新推荐文章于 2024-08-16 16:51:12 发布