一个自创的多线程池设计

最近看了些多线程方面的东西,感觉设计一个多线程池其实难度并不是很大,于是自己私下写了个简单的线程池,这个线程池只是实现了一些简单的功能,并没有涉及到线程同步方面的东西,这部分内容,我会持续更新,不断来优化这个线程池,先来看看代码吧,代码如下:

#ifndef __THREAD__H
#define __THREAD__H

#include <pthread.h>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <vector>
#include <boost/function.hpp>
#include <boost/bind.hpp>

enum threadState
{
    THREAD_NORMAL,
    THREAD_BUSY,
    THREAD_KILL
};

class Thread
{
   typedef  boost::function<void()> threadfun;
    public:
        Thread(const threadfun& funs,const std::string threadName = std::string()):fun(funs),threadName(threadName
        {
            threadHandle = -1;
            state = THREAD_NORMAL;
        }
        ~Thread(){}
        void setThreadFun(const threadfun& fun)
        {
            this->fun = fun;
        }
        void run();
        void stop();
    private:
        static void* start(void* arg)
        {
            Thread* thd = static_cast<Thread*>(arg);
            printf("%s:",thd->threadName.c_str());
            thd->fun();
            return NULL;

        }
    public:
        pthread_t threadHandle;
        threadfun fun;
        std::string threadName;
        threadState state;
};
class ThreadPool
{
    public:
        ThreadPool(const int threadNum):threadNum(threadNum)
        {
            threadPool.clear();
        }
        ~ThreadPool()
        {
        }
        void addThread(const int threadNum,boost::function<void()>& f);
        void delThread(const int threadNum);
        void schedule();
        void startAll();
        void stopAll();
        Thread* assignThread();
    private:
        int threadNum;
        std::vector<Thread*> threadPool;
};
#endif

在线程类中,我们主要是通过boost::function机制来为线程对象指定相应的回调函数,而线程池则是通过使用threadpool来管理创建的线程,想必其他的内容通过名字就知道其含义了,下面来看看具体的实现吧,代码如下:

#include "Thread.h"

void Thread::run()
{
    pthread_create(&threadHandle,NULL,&start,this);
}

void Thread::stop()
{
    pthread_join(threadHandle,NULL);
}

void ThreadPool::addThread(const int threadNum,boost::function<void()>& f)
{
    std::string threadName = "Thread";
    Thread* thread = NULL;
    for(int i = 0;i<threadNum;i++)
    {
        char buf[10];
        memset(buf,0,sizeof(buf));
        sprintf(buf,"%d",i);
        thread = new Thread(f,threadName+buf);
        assert(thread);
        threadPool.push_back(thread);
    }
}

void ThreadPool::delThread(const int threadNum)
{
    int size = (threadPool.size() > threadNum)? threadNum : threadPool.size();
    for(int i=0;i<size;i++)
    {
        if(threadPool[i] == NULL)
            continue;
        threadPool[i]->stop();
        delete threadPool[i];
        threadPool[i] = NULL;
    }
}
void ThreadPool::startAll()
{
    for(int i = 0;i<threadPool.size();i++)
    {
        if(threadPool[i] == NULL)
            continue;
        threadPool[i]->state = THREAD_BUSY;
        threadPool[i]->run();
    }
}

void ThreadPool::stopAll()
{
    for(int i = 0; i< threadPool.size();i++)
    {
        if(threadPool[i] == NULL)
            continue;
        threadPool[i]->state = THREAD_NORMAL;
    }
}

void ThreadPool::schedule()
{
    for(int i = 0;i<threadPool.size();i++)
    {
        if(threadPool[i] == NULL || threadPool[i]->state == THREAD_BUSY)
            continue;
        threadPool[i]->state = THREAD_BUSY;
        threadPool[i]->run();
        break;
    }
}

Thread* ThreadPool::assignThread()
{
    for(int i = 0; i<threadPool.size();i++)
    {
        if(threadPool[i] == NULL || threadPool[i]->state == THREAD_BUSY)
            continue;
        return threadPool[i];
    }
    return NULL;
}

接下来,我们再来看看相关的测试用例吧,代码如下:

#include "Thread.h"


void worker()
{
    printf("this is not arguments\n");
    //sleep(1);
}

void worker(int a,int b)
{
    int sum = a+b;
    printf("this is two arguments,sum=%d\n",sum);
    sleep(1);
}

void worker(int a,int b, int c)
{
    int sum = a+b+c;
    printf("this is three arguments,sum=%d\n",sum);
}
int main()
{
    int threadNum = 10;
    boost::function<void()> f = boost::bind(&worker);
    ThreadPool threadPool(10);
    threadPool.addThread(threadNum,f);

    threadPool.startAll();
    threadPool.stopAll();
    //threadPool.schedule();
    sleep(1);

    Thread* thread = threadPool.assignThread();
    assert(thread);

    int a,b;
    a = b = 3;
    boost::function<void()> f1 = boost::bind(&worker,a,b);
    thread->setThreadFun(f1);
    thread->run();
    sleep(1);

    int c = 4;
    boost::function<void()> f2 = boost::bind(&worker,a,b,c);
    thread = threadPool.assignThread();
    assert(thread);
    thread->setThreadFun(f2);
    thread->run();

    sleep(5);
    threadPool.delThread(threadNum);
    return 0;
}

我们可以自己来指定相关的回调函数给我们的线程,然后通过调用run函数来执行,实现方式很简单,有些内容完全可以优化,例如将指定的回调函数实现为对象的方式,这样的话,可以通过为线程指定任务的方式来处理,这样就能更加灵活,方便,这部分优化我将会放在下篇博文中,在此就不多说了,代码很基础,思想很简单,先看看吧,呵呵,多谢了。

总结

      这篇博文主要是在工作中涉及到的多线程,而私下想的东西,内容很简单,一个真正实用的多线程池要比这个复杂很多,但是思想应该是相通的,在后面的博文中,我会对这个线程池进行优化,也希望能够设计出一个很实用的线程池,有时候重复造轮子其实也是提高自己专业技能的一条捷径。

如果需要,请注明转载,多谢了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值