Skip to main content
edited tags
Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238
Source Link
Fibbs
  • 195
  • 1
  • 8

Reuseable C++11 Thread

I'm learning about threading support in C++. I've got a basic understanding of thread-pools and why creating and destroying threads on some systems can be expensive. As far as I'm aware C++11 doesn't have any built in support for worker/background threads. std::thread is only designed to perform one task which you set in the constructor; it then destroys the thread after the task is complete.

At the moment I have no use for a fully fledged thread-pool but I would like to be able to reuse a thread for different tasks after I create it. I've created a simple class that will accept any function or method wrapped in a lambda and will then execute it exactly once. The reusable thread object should not destruct until the work function is fully complete.

This is the implementation:

class Reusable_Thread
{
    public:
        Reusable_Thread()
            : m_thread_pause(true), m_thread_quit(false),
              m_thread(&Reusable_Thread::thread_worker, this)
        { }

        ~Reusable_Thread()
        {
            m_thread_quit = true;
            m_thread.join();
        }

        bool get_readiness() const { return m_thread_pause; }

        bool set_work(const std::function<void()>& work_func)
        {
            if (get_readiness())
            {
                m_work_func = work_func;
                return true;
            }
            else
            {
                return false;
            }
        }

    private:
        std::atomic<bool> m_thread_pause;
        std::atomic<bool> m_thread_quit;
        std::thread m_thread;
        std::function<void()> m_work_func;

        void thread_worker()
        {
            while (!m_thread_quit)
            {
                if (!m_thread_pause)
                {
                    m_work_func();
                    m_thread_pause = true;
                }
            }
        }
};

And this is some example usage:

int main()
{
    Reusable_Thread thread;

    auto f1 = [&] () { /* do some work */ };
    thread.set_work(f1);

    while (thread.get_readiness() == false)
    {
        // do some other stuff
    }

    // set some new work
    auto f2 = [&] () { /* do some new work */ };
    thread.set_work(f2);

    // maybe call f1 again, depends if f2 has finished yet
    if (!thread.set_work(f1))
    {
        // thread too busy to call f1, call it on the main thread
        f1();
    }

    // thread won't destruct until work has finished
    return 0;
}

Are there any problems with implementing a reusable thread this way?