Widnows 平台线程池

#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;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值