C++线程池实现

这是一个关于线程池实现的代码示例,定义了`ThreadPoolVito`类,包括Windows和非Windows平台的适配。类中包含工作线程`WorkThread`和任务`Task`的管理,支持添加任务到队列和线程池的关闭。在`test_threadPool`函数中展示了如何使用线程池执行任务,每个任务调用`vito_counter`函数,打印任务索引和线程ID。
摘要由CSDN通过智能技术生成

#ifndef THREAD_POOL_VITO_H
#define THREAD_POOL_VITO_H
#ifdef _WIN32
#include<windows.h>
#include<process.h>
#else
#include <pthread.h>
#endif


#define LL_ADD(item, list) do {                    \
    item->prev = NULL;                                \
    item->next = list;                                \
    if(list!= NULL) list->prev = item;                \
    list = item;                    \
} while(0)

#define LL_REMOVE(item, list) do {                        \
    if (item->prev != NULL) item->prev->next = item->next;    \
    if (item->next != NULL) item->next->prev = item->prev;    \
    if (list == item) list = item->next;                    \
    item->prev = item->next = NULL;                            \
} while(0)

class ThreadPoolVito;

//工作线程
class WorkThread
{
public:

#ifdef _WIN32
    HANDLE _handle;
    DWORD  _id;
#else
    pthread_t thread;
#endif

    int terminate;
    ThreadPoolVito *pWorkPool;
    WorkThread *prev;
    WorkThread *next;
};

//任务
class Task
{
public:
#ifdef _WIN32
    unsigned(__stdcall* task_fun)(Task *task);
#else
    void(*task_fun)(Task *task);
#endif
    void *user_data;
    Task *prev;
    Task *next;
};

class ThreadPoolVito
{
public:
    ThreadPoolVito(int numThread=1);
    ~ThreadPoolVito();
    void addTaskToQueue(Task *pTask);
    void threadPoolShutdown();

#ifdef _WIN32
    static unsigned int __stdcall workerThread(void* ptr);
#else
    static void * workerThread(void* ptr);
#endif

public:
    WorkThread *pWorker;
    Task *pTask;
#ifdef _WIN32
    mutable CRITICAL_SECTION taskMutex;
    mutable CONDITION_VARIABLE taskCond;
#else
    pthread_mutex_t taskMutex;
    pthread_cond_t taskCond;
#endif
};

#endif

#include "ThreadPoolVito.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

 

#ifdef _WIN32
unsigned int __stdcall ThreadPoolVito::workerThread(void* ptr)
{
    WorkThread *pWorker = (WorkThread*)ptr;
    while (true)
    {
        EnterCriticalSection(&pWorker->pWorkPool->taskMutex);
        while (pWorker->pWorkPool->pTask == NULL)
        {
            if (pWorker->terminate)
            {
                break;
            }
            SleepConditionVariableCS(&pWorker->pWorkPool->taskCond, &pWorker->pWorkPool->taskMutex, INFINITE);
        }

        if (pWorker->terminate)
        {
            LeaveCriticalSection(&pWorker->pWorkPool->taskMutex);
            break;
        }

        Task *pTask = pWorker->pWorkPool->pTask;
        if (pTask != NULL)
        {
            LL_REMOVE(pTask, pWorker->pWorkPool->pTask);
        }
        LeaveCriticalSection(&pWorker->pWorkPool->taskMutex);
        if (NULL == pTask)
        {
            continue;
        }
        pTask->task_fun(pTask);
    }

    free(pWorker);
    ExitThread(pWorker->_id);
}
#else
void *  ThreadPoolVito::workerThread(void* ptr)
{
    WorkThread *pWorker = (WorkThread*)ptr;
    while (true)
    {
        pthread_mutex_lock(&pWorker->pWorkPool->taskMutex);
        while (pWorker->pWorkPool->pTask == NULL)
        {
            if (pWorker->terminate)
            {
                break;
            }
            pthread_cond_wait(&pWorker->pWorkPool->taskCond, &pWorker->pWorkPool->taskMutex);
        }

        if (pWorker->terminate)
        {
            pthread_mutex_unlock(&pWorker->pWorkPool->taskMutex);
            break;
        }

        Task *pTask = pWorker->pWorkPool->pTask;
        if (pTask != NULL)
        {
            LL_REMOVE(pTask, pWorker->pWorkPool->pTask);
        }
        pthread_mutex_unlock(&pWorker->pWorkPool->taskMutex);
        if (NULL == pTask)
        {
            continue;
        }
        pTask->task_fun(pTask);
    }

    free(pWorker);
    pthread_exit(NULL);
}
#endif

 

ThreadPoolVito::ThreadPoolVito(int numThread)
{
    if (numThread < 1)
        numThread = 1;

    this->pTask = NULL;
    this->pWorker = NULL;


#ifdef _WIN32


    InitializeCriticalSection(&this->taskMutex);
    InitializeConditionVariable(&this->taskCond);

    int i = 0;
    for (i = 0; i < numThread; i++)
    {
        WorkThread *pWorker = (WorkThread*)malloc(sizeof(WorkThread));
        if (pWorker == NULL) {
            perror("malloc");
        }
        memset(pWorker, 0, sizeof(WorkThread));
        pWorker->pWorkPool = this;
        unsigned int id;
        pWorker->_handle = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, workerThread, (void*)pWorker, 0, &id));
        pWorker->_id = id;
        if (pWorker->_handle == NULL)
        {
            perror("pthread_create");
            free(pWorker);
        }
        LL_ADD(pWorker, this->pWorker);
    }
#else
    pthread_cond_t blank_cond = PTHREAD_COND_INITIALIZER;
    memcpy(&this->taskCond, &blank_cond, sizeof(this->taskCond));

    pthread_mutex_t blank_mutex = PTHREAD_MUTEX_INITIALIZER;
    memcpy(&this->taskMutex, &blank_mutex, sizeof(this->taskMutex));

    int i = 0;
    for (i = 0; i < numThread; i++)
    {
        WorkThread *pWorker = (WorkThread*)malloc(sizeof(WorkThread));
        if (pWorker == NULL) {
            perror("malloc");
        }

        memset(pWorker, 0, sizeof(WorkThread));
        pWorker->pWorkPool = this;

        int ret = pthread_create(&pWorker->thread, NULL, workerThread, (void *)pWorker);
        if (ret)
                {

            perror("pthread_create");
            free(pWorker);
        }

        LL_ADD(pWorker, this->pWorker);
    }
#endif
}


ThreadPoolVito::~ThreadPoolVito()
{

}

 

void ThreadPoolVito::addTaskToQueue(Task *pTask)
{
#ifdef _WIN32
    EnterCriticalSection(&this->taskMutex);
    LL_ADD(pTask, this->pTask);
    WakeConditionVariable(&this->taskCond);
    LeaveCriticalSection(&this->taskMutex);
#else
    pthread_mutex_lock(&this->taskMutex);
    LL_ADD(pTask, this->pTask);
    pthread_cond_signal(&this->taskCond);
    pthread_mutex_unlock(&this->taskMutex);
#endif
}


void ThreadPoolVito::threadPoolShutdown()
{
    WorkThread *pWorker = NULL;
    for (pWorker = this->pWorker; pWorker != NULL; pWorker = pWorker->next)
    {
        pWorker->terminate = 1;
    }
#ifdef _WIN32
    EnterCriticalSection(&this->taskMutex);
    this->pWorker = NULL;
    this->pTask = NULL;
    WakeAllConditionVariable(&this->taskCond);
    LeaveCriticalSection(&this->taskMutex);
#else
    pthread_mutex_lock(&this->taskMutex);
    this->pWorker = NULL;
    this->pTask = NULL;
    pthread_cond_broadcast(&this->taskCond);
    pthread_mutex_unlock(&this->taskMutex);
#endif
}

 

//#include "MutexVito.h"
//#include "ThreadVito.h"
//#include "CondVito.h"
#include "ThreadPoolVito.h"
#include<iostream>
#include<thread>
#include<stdio.h>
#include<stdlib.h>

#ifdef _WIN32
#include<windows.h>
#include<process.h>
#else
#include <pthread.h>
#include <unistd.h>
#endif

#define VITO_MAX_THREAD            30
#define VITO_COUNTER_SIZE        300

#ifdef _WIN32
unsigned int __stdcall vito_counter(Task *pTask)
#else
void vito_counter(Task *pTask)
#endif
{
    int index = *(int*)pTask->user_data;
    //printf("index : %d, selfid : %lu\n", index, GetCurrentThreadId());
    printf("index : %d, selfid : %lu\n", index, pthread_self());
    free(pTask->user_data);
    free(pTask);
    //return 0;
}

void test_threadPool()
{
    /*ThreadPoolStruct pool;
    threadPoolInit(&pool, VITO_MAX_THREAD);
    int i = 0;

    for (i = 0; i < VITO_COUNTER_SIZE; i++)
    {
        nTask *pTask = (nTask*)malloc(sizeof(nTask));
        if (pTask == NULL)
        {
            perror("malloc");
        }
        pTask->task_fun = vito_counter;
        pTask->user_data = malloc(sizeof(int));
        *(int*)pTask->user_data = i;

        addTaskToQueue(&pool, pTask);
    }*/

    ThreadPoolVito pool(VITO_MAX_THREAD);
    for (int i = 0; i < VITO_COUNTER_SIZE; i++)
    {
        Task *pTask = (Task*)malloc(sizeof(Task));
        if (pTask == NULL)
        {
            perror("malloc");
        }
        pTask->task_fun = vito_counter;
        pTask->user_data = malloc(sizeof(int));
        *(int*)pTask->user_data = i;
        pool.addTaskToQueue(pTask);
    }

    while (true)
    {
        sleep(2);
    }
}


int main()
{
    test_threadPool();
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值