线程池 (1)--任务队列模块

    线程池的思想早有耳闻,中间也涉及好多内容,回过头来重新设计一下线程池.

使用者视角:    

      1.创建一个线程池对象,      ThreadPool ThPool(int minThreads);      //同时会创建一个管理者线程,负责维护线程池,可以通过算法动态调度增加或减少线程

      2.加入一个任务         int ThPool.PushTask((void*)(*)(void),bool ifneedResult=false);      //如果不需要返回结果性能更好,返回一个key查询任务执行状态

      3.根据key得到任务执行结果     struct Result GetResult(int key)    //返回一个结果结构体,要求调用者先检查状态码,再使用val值

 

        enum Status{OK=0,BUSYING,TODO,NOSCUHTASK,ERROR,}    //任务状态 ----> 正常结束,忙,尚未执行,无此任务,出错

       struct Result{
          Status  flag;

          void * val;

       }

目标要求:

        1.涉及的互斥锁,条件变量,信号量全部使用c++11特性,方便在windows和linux下通用

        2.GetResult这个函数我有过诸多考虑,比如 通常实现都是对一个简单结果表上锁,获得锁,查询结果,再释放锁.  但是,这样做有一个小问题,

      每一个单独Thread在完成任务后都要把结果放入

 

 

//这其中也看过别人的线程池,不过绝大多数都是简单实现,我这个也不过是简单级里的复杂版....日后可能会对这个线程池进行改进

//这方面应该去看看Nginx这种工业级线程池实现......

 

比较长,所以分几部分,第一部分是 循环队列模板

#ifndef _LOOP_QUEUE
#define _LOOP_QUEUE

#pragma once

template<class T>                    //push满了会false,空pop会返回0,没有扩容
class Loop_Queue
{
    int m_capacity;
    T* arr;
    int front, rear;
    bool autoExpansion = false;            //自动扩容....TODO

public:
    explicit Loop_Queue(int capacity);
    ~Loop_Queue();
    bool Push(const T&val);
    T Pop();
    int GetSize();
    int GetCapacity();
    bool Empty();
    

};


#endif // !_LOOP_QUEUE

template<class T>
Loop_Queue<T>::Loop_Queue(int capacity)
{
    m_capacity = capacity;
    arr = new T[m_capacity + 1];
    front = rear = 0;

}

template<class T>
inline bool Loop_Queue<T>::Push(const T&val)
{
    if (rear != m_capacity) {        //判断满
        if (rear == front - 1)
            return false;
    }
    else {
        if (front == 0)
            return false;
    }

    arr[rear] = val;                //插入
    if (rear == m_capacity)        //尾部
        rear = 0;
    else
        ++rear;

    return true;

}

template<class T>
T Loop_Queue<T>::Pop()            //为空返回(T)0,用前先判断为空最好,想了下还是不抛异常好,虽然STL是这样做
{
    if (front == rear)
        return T(0);

    if (front != m_capacity)
        return arr[front++];
    else {
        front = 0;
        return arr[m_capacity];
    }
}

template<class T>
int Loop_Queue<T>::GetSize()
{

    if (front < rear) {
        return rear - front;
    }
    else {
        return rear + (m_capacity - front);
    }

    return 0;
}

template<class T>
inline int Loop_Queue<T>::GetCapacity()
{
    return m_capacity;
}

template<class T>
inline bool Loop_Queue<T>::Empty()
{
    if (front == rear)
        return true;
    else
        return false;
}

template<class T>
inline Loop_Queue<T>::~Loop_Queue()
{
    delete[] arr;
}

 

循环队列 模板几个要点:  队列唯一的构造函数是整形的有参构造,指定最大队列长度(元素数量)  

             当队列满时push操作会返回false,正常返回true, 当队列已经为空的时候返回T(0),强制要求模板T类型有int转换构造函数

             比如采用下面这个任务结构体

typedef struct Task_t{
    int key;
    void* (*work)(void*);
    void* arg;

    inline explicit Task_t(const int a=0) {        //使得可以(T)5  这样使用,或者T(5);
        key = a;
        work = NULL;
        arg = NULL;
    }
}Task_t;

 

posted @ 2018-12-04 10:41  戳戳熊  阅读(976)  评论(0编辑  收藏  举报