jeudi 23 juillet 2015

c++11 thread pool make lock free

Hi now I'm trying to make ThreadPool with c++11

http://ift.tt/RuwJxv

i make thread pool based with this article.

I seperate ThreadPool and TaskPool. at ThreadPool method and Work Threads use lock_guard and unique_lock using TaskPool's mutex.

this is my code

class TaskPool
{
    private:
    using func = std::function<void()>;
    std::deque<func> tasks;
    std::condition_variable cv;

    bool is_empty()
    {
        bool ret;
        {
            std::unique_lock<std::mutex> lock(task_mutex);
            ret = tasks.empty();
        }
        return ret;
    }
public:
    std::mutex task_mutex;

    template <typename F>
    void add_task(F f)
    {
        {
            std::lock_guard<std::mutex> lg(task_mutex);
            tasks.push_back(func(f));
        }
        cv.notify_one();
    }

    func get_task()
    {
        func ret;
        {
            std::lock_guard<std::mutex> lg(task_mutex);
            ret = tasks.front();
            tasks.pop_front();
        }
        return ret;
    }

    void wait_task()
    {
        if (is_empty())
        {
            std::unique_lock<std::mutex> lock(task_mutex, std::defer_lock);
            cv.wait(lock, [] {return true; });
        }
    }
};



class Worker
{
public:
    Worker(TaskPool &s, std::shared_future<void> sf) : pool(s), end(sf) { }
    void operator()();
private:
    TaskPool &pool;
    std::shared_future<void> end;
};

void Worker::operator()()
{
    try {
        std::function<void()> task;
        while (true)
        {
            {
                std::lock_guard<std::mutex> lg(pool.task_mutex);
                while (end.valid())
                {
                    pool.wait_task();
                    task = pool.get_task();
                }
            }

            if (!end.valid())
            {
                return;
            }

            task();
        }
    }
    catch (std::exception e)
    {
        std::cerr << e.what() << std::endl;
    }
}



class ThreadPool
{
private:
    std::vector<std::thread> Threads;
    std::promise<void> pr;
public:
    ThreadPool(TaskPool& tp, const int pool_size)
    {
        std::shared_future<void> sf = std::shared_future<void>(pr.get_future());
        for (int i = 0; i < pool_size; i++)
        {
            Threads.push_back(std::thread(Worker(tp, sf)));
        }
    }

    ThreadPool::~ThreadPool()
    {
        pr.set_value();
        // join them
        for (size_t i = 0; i<Threads.size(); ++i)
            Threads[i].join();
    }
};

am i have wrong thingk using mutex?

Aucun commentaire:

Enregistrer un commentaire