线程类封装(3)

ThreadPool.hpp

 

#ifndef THREAD_THREADPOOL_HPP_
#define THREAD_THREADPOOL_HPP_


// #include <standard C library headers>
#include <time.h>
#include <assert.h>

// #include <standard C++ library headers>
#include <list>

// #include <other library headers>

// #include "custom headers"
#include "thread.hpp"
#include "mutex.hpp"


namespace thread
{


    class Stopable
    {
    public:
        Stopable() : stop(false) {}
        virtual ~Stopable() {}

    public:
        bool GetStop() const { return stop; }
        void SetStop(bool value = true) { stop = value;}

    private:
        bool stop;
    };


    class Task
    {
    public:
        virtual ~Task() {}
        virtual void Run() = 0;
    };


    class TaskQueue
    {
    public:
        TaskQueue() {}
        /*virtual*/ ~TaskQueue() {}

    public:
        void Push(Task* t) { Lock l(mutex); coll.push_back(t); }
        Task* Pop();
        bool Priority(Task* t);
        int Size() const { return coll.size(); }
        void Clear() { Lock l(mutex); coll.clear(); }
        const std::list<Task*> ToList() const { Lock l(mutex); return coll; }

    private:
        std::list<Task*> coll;
        mutable Mutex mutex;
    };


    class TaskThread : public Thread
    {
    public:
        TaskThread(TaskQueue& q) : queue(q), currentTask(NULL) {}
        virtual ~TaskThread() { WaitForEnd(); }

    public:
        bool GetRunning() const { return (currentTask != NULL); }
        Task* GetCurrentTask() { return currentTask; }
        int GetIdleTime() const { return (time(NULL) - idleStart); }

    protected:
        virtual void Run(const ThreadData& data, void* arg);

    private:
        TaskQueue& queue;
        Task* currentTask;
        int idleStart;
    };


    class ThreadPool
    {
    public:
        /**
         * @param min min threads
         * @param max max threads
         * @param idle in seconds
         */
        ThreadPool(int max = 100, int idle = 60)
            : maxThread(max), idleTime(idle), histThread(0) {}
        /*virtual*/ ~ThreadPool() { Stop(); }

    private:
        ThreadPool(const ThreadPool& rhs);
        ThreadPool& operator=(const ThreadPool& rhs);

    public:
        void Add(Task* t);
        void Priority(Task* t);
        void Stop();
        std::list<Task*> GetRunningTasks() const;
        std::list<Task*> GetPendingTasks() const { return queue.ToList(); }
        void ClearPendingTasks() { queue.Clear(); }
        int GetPendingTaskCount() const { return queue.Size(); }
        int GetThreadCount() const{ return threads.size(); }
        int GetIdleThreadCount() const;
        int GetHistThreadCount() const { return histThread; }
        int GetMaxThread() const { return maxThread; }
        void SetMaxThread(const int& value) { maxThread = value; }
        int GetIdleTime() const { return idleTime; }
        void SetIdleTime(const int& value) { idleTime = value; }

    protected:

    private:
        bool RemoveOneIdleTimeoutThread();
        void RemoveStopedThreads();
        void AddThread(int count);

    private:
        std::list<TaskThread*> threads;
        std::list<TaskThread*> stopThreads;
        TaskQueue queue;
        int maxThread;
        int idleTime;
        int histThread;
    };


    inline Task* TaskQueue::Pop()
    {
        Lock l(mutex);
        Task* t = NULL;
        if (coll.size() > 0)
        {
            t = coll.front();
            coll.pop_front();
        }
        return t;
    }


    inline bool TaskQueue::Priority(Task* t)
    {
        Lock l(mutex);
        std::list<Task*>::iterator i;
        for (i = coll.begin(); i != coll.end(); ++i)
        {
            if (*i == t)
            {
                coll.erase(i);
                coll.push_front(t);
                return true;
            }
        }
        return false;
    }


    inline void TaskThread::Run(const ThreadData& data, void* arg)
    {
        idleStart = time(NULL);
        do
        {
            currentTask = queue.Pop();
            if (currentTask != NULL)
            {
                currentTask->Run();
                currentTask = NULL;
                idleStart = time(NULL);
            }
            Sleep(1);
        }
        while (!data.GetStop());
    }


    inline void ThreadPool::Add(Task* t)
    {
        assert(t != NULL);

        queue.Push(t);
        if (queue.Size() > GetIdleThreadCount()) // may be need add new thread
        {
            int need1 = maxThread - GetThreadCount();
            int need2 = queue.Size() - GetIdleThreadCount();
            int count = (need1 > need2) ? need2 : need1;
            AddThread(count);
        }
        else                    // may be need delete idle timeout thread
        {
            while (RemoveOneIdleTimeoutThread())
            {
            }
        }
        RemoveStopedThreads();
    }


    inline void ThreadPool::Priority(Task* t)
    {
        if (queue.Priority(t))
        {
            TaskThread* thread = new TaskThread(queue);
            thread->Start();
            thread->SetStop();
            stopThreads.push_back(thread);
            histThread++;
        }
    }


    inline void ThreadPool::Stop()
    {
        std::list<TaskThread*>::iterator i;
        for (i = threads.begin(); i != threads.end(); ++i)
        {
            (*i)->SetStop();
        }
        for (i = stopThreads.begin(); i != stopThreads.end(); ++i)
        {
            delete (*i);
        }
        stopThreads.clear();
        for (i = threads.begin(); i != threads.end(); ++i)
        {
            delete (*i);
        }
        threads.clear();
    }


    inline std::list<Task*> ThreadPool::GetRunningTasks() const
    {
        std::list<Task*> col;
        std::list<TaskThread*>::const_iterator i;
        for (i = threads.begin(); i != threads.end(); ++i)
        {
            Task* t = (*i)->GetCurrentTask();
            if (t != NULL)
            {
                col.push_back(t);
            }
        }
        for (i = stopThreads.begin(); i != stopThreads.end(); ++i)
        {
            Task* t = (*i)->GetCurrentTask();
            if (t != NULL)
            {
                col.push_back(t);
            }
        }
        return col;
    }


    inline int ThreadPool::GetIdleThreadCount() const
    {
        int count = 0;
        for (std::list<TaskThread*>::const_iterator i = threads.begin();
             i != threads.end(); ++i)
        {
            count += ((*i)->GetRunning() ? 0 : 1);
        }
        return count;
    }


    inline bool ThreadPool::RemoveOneIdleTimeoutThread()
    {
        for (std::list<TaskThread*>::iterator i = threads.begin();
             i != threads.end(); ++i)
        {
            if ((!(*i)->GetRunning()) && ((*i)->GetIdleTime() > idleTime))
            {
                (*i)->SetStop();
                stopThreads.push_back(*i);
                threads.erase(i);
                return true;
            }
        }
        return false;
    }


    inline void ThreadPool::RemoveStopedThreads()
    {
        std::list<TaskThread*> tmp;
        for (std::list<TaskThread*>::iterator i = stopThreads.begin();
             i != stopThreads.end(); ++i)
        {
            if ((*i)->IsAlive())
            {
                tmp.push_back(*i);
            }
            else
            {
                delete *i;
            }
        }
        stopThreads.swap(tmp);
    }


    inline void ThreadPool::AddThread(int count)
    {
        for (int i = 0; i < count; i++)
        {
            TaskThread* thread = new TaskThread(queue);
            thread->Start();
            threads.push_back(thread);
            histThread++;
        }
    }


}


#endif // THREAD_THREADPOOL_HPP_

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值