C++写的线程池

线程池,就是事先创建好多那个线程,抽象成一个装有多个线程的池子,或者说是缓冲区,用来处理外部的操作请求。

首先得弄明白一个问题:为什么需要创建线程池。

我个人的看法:在多线程编程当中,处理不同的请求,往往是放在一个线程当中,但是当请求数到达一定程度时,不管理这些线程容易造成程序混乱。另外一个优点就是节省了创建线程的时间,这在大量快速请求的情况下,性能方面显得尤为突出。

线程池其实就是一个线程的缓冲区,首先我们先创建好一个任务队列,然后在创建多个线程的集合,具体的抽象按自己的需要而定。然后就是多个线程调度任务队列,每当线程处于空闲时就会调用一个任务,让自己处于忙状态。如果所有线程都处于忙,则新增的任务进行排队,等待调度。

任务队列的抽象:一个链式队列,数据是任务的处理函数以及函数的入参。

线程池的抽象:任务队列的头指针,当前的任务数,最大的线程数目

代码如下:

#ifndef THREADPOOL_H
#define THREADPOOL_H
#include <pthread.h>
#include <unistd.h>
#include <iostream>

//define task queue
typedef struct _TASK_QUEUE
{
    void *(*event)(void *);
    void *arg;
    struct _TASK_QUEUE *next;
}TASK_QUEUE;

//static void *process(void *arg);

class threadpool
{
private:
    unsigned long m_ulMaxThreadNum;
    unsigned long m_ulSize; // current task queue length
    TASK_QUEUE *m_pTaskHead;//task list's head
    TASK_QUEUE *m_pTaskTail;//task list's tail
    pthread_t *m_pthreadBase; //pthread id 
    pthread_mutex_t m_queueMutex;
    pthread_cond_t m_queueCond;
    bool m_closeFlag;
public:
    threadpool();
    ~threadpool();
    void initPool(unsigned long num);
    void destroyPool();
    void addTask(void *(*event)(void *), void *arg);
    void rmCurrTask();
    static void *process(void *arg);
};
#endif

#include "threadpool.h"

pthread_attr_t SetPthreadAttr(int more_mem)
{
    pthread_attr_t attr;
    int stacksize;
    int ret;
    ret = pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    stacksize = (PTHREAD_STACK_MIN + more_mem);
    ret = pthread_attr_setstacksize(&attr, stacksize);
    return attr;
}


threadpool::threadpool()
{
    m_pTaskHead = NULL;
    m_pTaskTail = NULL;
    m_pthreadBase = NULL;
    m_ulMaxThreadNum = 0;
    m_ulSize = 0;
    m_closeFlag = 1;
    pthread_mutex_init(&m_queueMutex, NULL); 
    pthread_cond_init(&m_queueCond, NULL); 
}

threadpool::~threadpool()
{

}

void threadpool::initPool(unsigned long num)
{
    m_ulMaxThreadNum = num;
    m_closeFlag = 0;
    pthread_mutex_init(&m_queueMutex, NULL);
    pthread_cond_init(&m_queueCond, NULL);
    m_pthreadBase = new pthread_t [m_ulMaxThreadNum];
    pthread_t pthreadId;
    for(int i = 0; i < num; ++i)
    {
        pthread_create(&pthreadId, NULL, process, this);
        m_pthreadBase[i] = pthreadId;
        printf("create a thread.\n");
    }
}

void threadpool::destroyPool()
{
    m_closeFlag = 1;
    pthread_cond_broadcast(&m_queueCond);
    for(int i = 0; i < m_ulMaxThreadNum; ++i)
    {   
        pthread_join(m_pthreadBase[i], NULL);
    }   
    pthread_mutex_destroy(&m_queueMutex); 
    pthread_cond_destroy(&m_queueCond);     
    delete []m_pthreadBase;
    m_pthreadBase = NULL;
    m_ulMaxThreadNum = 0;
    TASK_QUEUE *pTmp = NULL;
    while(m_pTaskHead)
    {
        pTmp = m_pTaskHead;
        m_pTaskHead = m_pTaskHead->next;
        free(pTmp);
    }
    m_pTaskTail = NULL;
}

void threadpool::addTask(void *(*event)(void *), void *arg)
{
    TASK_QUEUE *pstNewTask = new TASK_QUEUE;
    memset(pstNewTask, 0, sizeof(TASK_QUEUE));
    pstNewTask->event = event;
    pstNewTask->arg = arg;
    pstNewTask->next = NULL;
    pthread_mutex_lock(&m_queueMutex);
    if(!m_pTaskHead)
    {
        m_pTaskHead = pstNewTask;
        m_pTaskHead->next = NULL;
        m_pTaskTail = m_pTaskHead;
        m_ulSize++;
    }
    else
    {
        m_pTaskTail->next = pstNewTask;
        m_pTaskTail = pstNewTask;
        m_ulSize++;
    }    pthread_cond_signal(&m_queueCond);    pthread_mutex_unlock(&m_queueMutex);
    //printf("Add a task to task queue\n");
}

void threadpool::rmCurrTask()
{
    TASK_QUEUE *pTmp = NULL;    
    if(!m_pTaskHead)
    {
        printf("TaskQueue is empty.\n");
        return;
    }
    pTmp = m_pTaskHead;
    m_pTaskHead = m_pTaskHead->next;
    m_ulSize--;    
    delete pTmp;    
    //printf("Remove a task from queue.\n");
}

void *threadpool::process(void *arg)
{
    threadpool *pcPool = (threadpool *)arg;
    TASK_QUEUE stTaskProc;
    while(1)
    {
        pthread_mutex_lock(&pcPool->m_queueMutex);
        if(pcPool->m_closeFlag)
        {
            pthread_mutex_unlock(&pcPool->m_queueMutex);
            printf("Exit.\n");
            pthread_exit(NULL);
        }        

        if(!pcPool->m_pTaskHead) 
        {
            pthread_cond_wait(&pcPool->m_queueCond, &pcPool->m_queueMutex);
            printf("Recv a signal.\n");
            //pthread_mutex_unlock(&pcPool->m_queueMutex);
        }        
        
        if(pcPool->m_pTaskHead)
        {
            memset(&stTaskProc, 0, sizeof(TASK_QUEUE));
            memcpy(&stTaskProc, pcPool->m_pTaskHead, sizeof(TASK_QUEUE));
            //run event
            pcPool->rmCurrTask();
            pthread_mutex_unlock(&pcPool->m_queueMutex);
            stTaskProc.event(stTaskProc.arg);
        }
        else
            pthread_mutex_unlock(&pcPool->m_queueMutex); 
    }
    pthread_exit(NULL);
}


#if 0
void taskevent(void *arg)
{
    printf("%^&*()_\n");
}


void *hello(void *arg)
{
    threadpool *pcPool = (threadpool *)arg;
    while(1)
    {
        pcPool->addTask((void* (*)(void*))taskevent, NULL);
        printf("hello kitty.\n");
        sleep(1);
    }
    printf("Never should be here.\n");
}


int main()
{
    threadpool pool;
    pool.initPool(10);
    sleep(1);
    pthread_attr_t attr;
    attr = SetPthreadAttr(10240);
    pthread_t pthreadTmp;
    pthread_create(&pthreadTmp, &attr, hello, &pool);
    while(1)
    {
        sleep(1);
    }
    return 0;
}
#endif




 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值