Search code examples
c++mutexcondition-variable

How would I add a condition variable here?


I'm trying to add a condition variable to my code which is using the farming pattern, but I cannot understand where to use it. I thought I could use a condition variable to pause threads while they are not being used. Could anybody show me an example or point me in the right direction?

When I have attempted, by checking if the tasks are empty, I have just been left "waiting"

Farm.cpp

void Farm::run()
{
    //list<thread *> threads;
    vector<thread *> threads;

    for (int i = 0; i < threadCount; i++)
    {
        threads.push_back(new thread([&]
        {
            while (!taskQ.empty())
            {

                taskMutex.lock();
                RowTask* temp = taskQ.front();
                taskQ.pop();
                taskMutex.unlock();
                temp->run(image_);
                delete temp;
            }

            return;
        }));
    }

    for (auto i : threads)
    {
        i->join();
    }
}

Solution

  • A basic idea for a queue implementation using a condition variable:

    #include <queue>
    #include <mutex>
    #include <condition_variable>
    
    template<typename T>
    class myqueue {
        std::queue<T> data;
        std::mutex mtx_data;
        std::condition_variable cv_data;
    
    public:
        template<class... Args>
        decltype(auto) emplace(Args&&... args) {
            std::lock_guard<std::mutex> lock(mtx_data);
            auto rv = data.emplace(std::forward<Args>(args)...);
            cv_data.notify_one(); // use the condition variable to signal threads waiting on it
            return rv;
        }
    
        T pop() {
            std::unique_lock<std::mutex> lock(mtx_data);
            while(data.size() == 0) cv_data.wait(lock); // wait to get a signal
            T rv = std::move(data.front());
            data.pop();
            return rv;
        }
    };