C ++ 11 using Object Pool object pool (rpm)

Many systems have access to the quickness and predictability of resources stringent requirements, including internet access included, object instance, threads and memory. But also requires scalable solution, able to cope with the situation there are a lot of resources.

object pool for the recycling of specific types of objects, these objects are either created huge overhead, or a limited number can be created. And the object needs to be done in a pool of stateless.

Then turn the blogger code, still studying

const int MaxObjectNum = 10;
template <typename T>
class ObjectPool
{
    template <typename... Args>
    using Constructor = std::function<std::shared_ptr<T>(Args...)>;

public:
    ObjectPool(void)
        : m_bNeedClear(false)
    {
    }

    virtual ~ObjectPool(void)
    {
        m_bNeedClear = true;
    }

    template <typename... Args>
    void Init(size_t num, Args &&... args)
    {
        if (num <= 0 || num > MaxObjectNum)
        {
            throw std::logic_error("object num out of range.");
        }

        auto constructName = typeid(Constructor<Args...>).name();

        for (size_t i = 0; i < num; i++)
        {
            m_object_map.emplace(constructName,
                                 std::shared_ptr<T>(new T(std::forward<Args>(args)...), [constructName, this](T *t) {
                                     if (m_bNeedClear)
                                     {
                                         delete t;
                                     }
                                     else
                                     {
                                         m_object_map.emplace(constructName, std::shared_ptr<T>(t));
                                     }
                                 }));
        }
    }

    template <typename... Args>
    std::shared_ptr<T> Get()
    {
        string constructName = typeid(Constructor<Args...>).name();

        auto range = m_object_map.equal_range(constructName);

        for (auto it = range.first; it != range.second; ++it)
        {
            auto ptr = it->second;
            m_object_map.erase(it);
            return ptr;
        }

        return nullptr;
    }

private:
    std::multimap<std::string, std::shared_ptr<T>> m_object_map;
    bool m_bNeedClear;
};
ObjectPool.cpp
class BigObject
{
public:
    BigObject() {}

    BigObject(int a) {}

    BigObject(const int &a, const int &b)
    {
    }

    void Print(const string &str)
    {
        cout << str << endl;
    }
};

void Print(shared_ptr<BigObject> p, const string &str)
{
    if (p != nullptr)
    {
        p->Print(str);
    }
}

int main()
{
    ObjectPool<BigObject> pool;
    pool.Init(2);
    {
        auto p = pool.Get();
        Print(p, "p");

        auto p2 = pool.Get();
        Print(p2, "p2");
    }

    auto p = pool.Get();
    Print(p, "p");

    auto p2 = pool.Get();
    Print(p2, "p2");

    auto p3 = pool.Get();
    Print(p3, "p3");

    pool.Init(2, 1);

    auto p4 = pool.Get<int>();

    Print(p4, "p4");
    getchar();
    return 0;
}
test.cpp

 There is a semi-synchronous half asynchronous thread pool, I understand this a little more, it is to use queues and semaphores to implement multithreading

#include <list>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <iostream>
#include <functional>
#include <memory>
#include <atomic>
using namespace std;

namespace itstation
{
template <typename T>
class SynaQueue
{
public:
    SynaQueue(int maxSize)
        : m_maxSize(maxSize), m_needStop(false)
    {
    }

    void Put(const& T X) 
    { 
        the Add (X); 
    } 
    void of Put (T && X) 
    { 
        the Add (Forward <T> (X)); // Perfect forward, without changing the type of the parameter 
    }
     void the Take (List <T> & List ) 
    { 
        STD :: unique_lock is <the mutex> Locker (m_mutex);
         // Analyzing formula, when the condition is not satisfied, will release the mutex condition variable, and the thread is placed in the waiting state, waiting for another thread invokes notify_one / all wake it up .
        // When the meet which continues when a condition, the task of removing the queue, waiting threads wake add tasks
         // when in a state of waiting thread wakes up, first get mutex, check whether the conditions are met, meet - to continue, otherwise, continue to wait for the release mutex 
        m_notEmpty.wait (Locker, [ the this ] { return m_needStop || NotEmpty(); });
        if (m_needStop)
            return;
        list = move(m_queue);
        m_notFull.notify_one();
    }
    void Take(T &t)
    {
        unique_lock<mutex> locker(m_mutex); //
        m_notEmpty.wait(locker, [this] { return m_needStop || NotEmpty(); });
        if (m_needStop)
            return;
        t = m_queue.front();
        m_queue.pop_front();
        m_notFull.notify_one (); 
    } 
    voidSTOP () 
    { 
        { 
            lock_guard <mutex> Locker (m_mutex); 
            m_needStop = to true ; 
        } 
        m_notFull.notify_all (); // all waiting threads all wake up, wake up the process of checking m_needStop, is true, all the threads withdraw 
        m_notEmpty.notify_all (); 
    } 

Private :
     BOOL NotFull () const 
    { 
        BOOL full = m_queue.size ()> = m_maxSize;
         IF (full) 
            COUT << " buffer is full, wait .... " !<< endl;
         return Full; 
    } 
    BOOL the NotEmpty () const 
    { 
        BOOL empty = m_queue.empty ();
         IF (empty) 
            COUT << " buffer empty, wait, ... asynchronous thread layer: " << this_thread get_id :: () << endl;
         return ! empty; 
    } 

    Template <F. typename>
     void the Add (&& F. X) 
    { 
        unique_lock is <the mutex> Locker (m_mutex);                                  // get a write lock by m_mutex 
        m_notFull.wait (Locker, [ the this ] { return m_needStop NotFull || ();}); // not full and stopped, and is released m_mutex Waiting; there is a continuing with the true 
        IF (m_needStop)
             return ; 
        m_queue.push_back (Forward <F.> (X)); 
        m_notEmpty.notify_one (); 
    } 

Private : 
    List <T> m_queue;                // buffer 
    the mutex m_mutex;                  // mutex 
    condition_variable m_notEmpty; // condition variable 
    condition_variable m_notFull;
     int m_maxSize;    // synchronization maximum queue size
     BOOL m_needStop; // stop sign 
};

const int MaxTaskCount = 100;
class ThreadPool
{
public:
    using Task = function<void()>;
    ThreadPool(int numThread = thread::hardware_concurrency())
        : m_queue(MaxTaskCount)
    {
        Start(numThread);
    }

    virtual ~ThreadPool()
    {
        Stop();
    }

    void Stop()
    {
        call_once(m_flag, [this] { StopThreadGroup(); });
    }

    void AddTask(Task &&task)
    {
        m_queue.Put(forward<Task>(task));
    }

    void AddTask(const Task &task)
    {
        m_queue.Put(task);
    }

private:
    void Start(int numThreads)
    {
        m_running = true;
        //创建线程组
        for (int i = 0; i < numThreads; i++)
        {
            m_threadgroup.emplace_back (make_shared <Thread> (:: & RunInThread the ThreadPool, the this StopThreadGroup ())); 
        } 
    } 

    // each thread executing this function 
    void RunInThread () 
    { 
        the while (m_running) 
        { 
            // get tasks are performed 
            List <the Task> List; 
            m_queue.Take (List); 
            for (Auto & Task: List ) 
            { 
                IF ! ( m_running)
                     return ; 

                Task (); 
            } 
        } 
    } 
    void 
    { 
        m_queue.Stop ();     // synchronization queue thread stops 
        m_running = to false ; // let out of the loop and the internal thread Release 
        for (Auto Thread: m_threadgroup) 
        { 
            IF (Thread) 
                Thread -> the Join (); 
        } 
        m_threadgroup.clear (); 
    } 

Private : 
    List <the shared_ptr <thread >> m_threadgroup; // thread processing task group, the list stores a pointer pointing to the shared thread 
    SynaQueue <the task> m_queue;                 // synchronous queue 
    atomic_bool m_running;                   // whether to stop the logo 
    once_flag m_flag; 
}; 
} // namespace itstation
ObjectPool.h
#include <stdio.h>
#include <iostream>
#include "ObjectPool.h"
#include <list>
using namespace std;
using namespace itstation;

void TestThreadPool()
{
    ThreadPool pool(2);
    thread thd1([&pool] {
        for (int i = 0; i < 10; i++)
        {
            auto thrID = this_thread::get_id();
            pool.AddTask([thrID, i] {cout << "Sync layer of threads in a thread ID 1: " << << THRID "   This is the task " << endl << I; :: sleep_for, which this_thread (Chrono seconds The :: ( 2 ));}); 
        } 
    }); 

    Thread THD2 ( [ & the pool] {
         for ( int I = 0 ; I < 10 ; I ++ ) 
        { 
            Auto THRID = this_thread :: get_id (); 
            pool.AddTask ([THRID, I] {COUT << " sync layer thread ID of the thread 2 : " << THRID << "   this is the task " << i << endl;this_thread::sleep_for(chrono::seconds( 2 ));});
        }
    });

    this_thread::sleep_for(chrono::seconds(45));
    pool.Stop();
    thd1.join();
    thd2.join();
}
int main()
{
    TestThreadPool();

    getchar();
    return 0;
}
test.cpp

 

Guess you like

Origin www.cnblogs.com/BobHuang/p/11259471.html