(Original) C ++ semi-synchronous, asynchronous half thread pool 2 (original) C ++ semi-synchronous, asynchronous thread pool half

(Original) C ++ semi-synchronous, asynchronous half thread pool

c ++ 11 boost technology exchange group: 296 561 497, welcome to exchange technology.

Thread pool can efficiently handle the task, the thread pool open multiple threads, waiting for the arrival of the synchronization task queue, the task multiple threads will come rushing to perform a task, when the task at hand too much, take a moment to reach the upper limit, the task The upper limit to ensure that the memory does not overflow. Efficiency cpu thread pool and the number of nuclear-related, multi-core, then the higher the efficiency, the number of threads and generally the number of cpu +2 more appropriate, or too many threads, thread switching frequently but will result in reduced efficiency.

Thread pool has two active process: 1 out non-stop to thread pool add tasks; 2 internal thread pool to take non-stop task execution... Activity diagram is as follows:

Queue thread pool is on the blog post with the synchronization queue. Specific code:

 
#include<vector>
#include<thread>
#include<functional>
#include<memory>
#include <atomic>
#include"SyncQueue.hpp"

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

    ~ThreadPool(void)
    {
        //如果没有停止时则主动停止线程池
        Stop();
    }

    void Stop()
    {
        std::call_once(m_flag, [this]{StopThreadGroup(); });// ensure multiple threads is called only once StopThreadGroup 
    }

    void AddTask(Task&&task)
    {
        m_queue.Put(std::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.push_back(std::make_shared<std::thread>(&ThreadPool::RunInThread, this));
        }
    }    

    void RunInThread()
    {
        while (m_running)
        {
            //取任务分别执行
            std::list<Task> list;
            m_queue.Take (List); 
    STD: : list <std :: shared_ptr <std :: thread >> m_threadgroup; // set of threads processing tasks

            for (Auto & Task: List) 
            { 
                (! m_running) IF 
                    return; 

                Task (); 
            } 
        } 
    } 

    void StopThreadGroup () 
    { 
        m_queue.Stop (); // make the synchronization queue thread stops 
        m_running = false; // set false, so that the internal thread out of the loop and exit 

        for (auto thread: m_threadgroup) // wait for the end of the thread 
        { 
            IF (the thread) 
                the Thread-> the Join (); 
        } 
        m_threadgroup.clear (); 
    }

    SyncQueue <Task> m_queue; // synchronous queue      
    atomic_bool m_running; // whether the stop flag 
    STD :: once_flag M_FLAG; 
};
 

 The above code uses synchronous queue SyncQueue, it is achieved here . Test code is as follows:

 
void TestThdPool()
{
    ThreadPool pool;bool runing = true;

    std::thread thd1([&pool,&runing]{
        while(runing)
        {
            cout<<"produce "<<this_thread::get_id()<< endl;

            pool.AddTask([]{
                std::cout <<"consume "<<this_thread::get_id()<< endl;
            });
        }
    });


    this_thread::sleep_for(std::chrono::seconds(10));
    runing = false;
    pool.Stop();
    
    thd1.join();
    getchar();
}
 

The above test code, thd1 is the producer thread, internal thread pool will continue to consume tasks producers generated. When you need to stop thread pool advance, just call Stop function on the line.

A little dream: to do its force, so that the c ++ world a better place!

c ++ 11 boost technology exchange group: 296 561 497, welcome to exchange technology.

Thread pool can efficiently handle the task, the thread pool open multiple threads, waiting for the arrival of the synchronization task queue, the task multiple threads will come rushing to perform a task, when the task at hand too much, take a moment to reach the upper limit, the task The upper limit to ensure that the memory does not overflow. Efficiency cpu thread pool and the number of nuclear-related, multi-core, then the higher the efficiency, the number of threads and generally the number of cpu +2 more appropriate, or too many threads, thread switching frequently but will result in reduced efficiency.

Thread pool has two active process: 1 out non-stop to thread pool add tasks; 2 internal thread pool to take non-stop task execution... Activity diagram is as follows:

Queue thread pool is on the blog post with the synchronization queue. Specific code:

 
#include<vector>
#include<thread>
#include<functional>
#include<memory>
#include <atomic>
#include"SyncQueue.hpp"

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

    ~ThreadPool(void)
    {
        //如果没有停止时则主动停止线程池
        Stop();
    }

    void Stop()
    {
        std::call_once(m_flag, [this]{StopThreadGroup(); }); //保证多线程情况下只调用一次StopThreadGroup
    }

    void AddTask(Task&&task)
    {
        m_queue.Put(std::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.push_back(std::make_shared<std::thread>(&ThreadPool::RunInThread, this));
        }
    }    

    void RunInThread()
    {
        while (m_running)
        {
            //取任务分别执行
            std::list<Task> list;
            m_queue.Take(list);

            for (auto& task : list)
            {
                if (!m_running)
                    return;

                task();
            }
        }
    }

    void StopThreadGroup()
    {
        m_queue.Stop(); //让同步队列中的线程停止
        m_running = false; //置为false,让内部线程跳出循环并退出

        for (auto thread : m_threadgroup) //等待线程结束
        {
            if (thread)
                thread->join();
        }
        m_threadgroup.clear();
    }

    std::list<std::shared_ptr<std::thread>> m_threadgroup; //处理任务的线程组
    SyncQueue<Task> m_queue; //同步队列     
    atomic_bool m_running; //是否停止的标志
    std::once_flag m_flag;
};
 

 上面的代码中用到了同步队列SyncQueue,它的实现在这里。测试代码如下:

 
void TestThdPool()
{
    ThreadPool pool;bool runing = true;

    std::thread thd1([&pool,&runing]{
        while(runing)
        {
            cout<<"produce "<<this_thread::get_id()<< endl;

            pool.AddTask([]{
                std::cout <<"consume "<<this_thread::get_id()<< endl;
            });
        }
    });


    this_thread::sleep_for(std::chrono::seconds(10));
    runing = false;
    pool.Stop();
    
    thd1.join();
    getchar();
}
 

上面的测试代码中,thd1是生产者线程,线程池内部会不断消费生产者产生的任务。在需要的时候可以提前停止线程池,只要调用Stop函数就行了。

Guess you like

Origin www.cnblogs.com/leijiangtao/p/12076614.html