I'm writing a thread safe queue using C++11 and stl threading. The WaitAndPop method currently looks like the following. I would like to be able to pass something to WaitAndPop that indicates if the calling thread has been asked to stop. WaitAndPop should return true if it waited for and returned an element of the queue, it should return false if the calling thread is being stopped.
bool WaitAndPop(T& value, std::condition_variable callingThreadStopRequested)
{
std::unique_lock<std::mutex> lock(mutex);
while( queuedTasks.empty() )
{
queuedTasksCondition.wait(lock);
}
value = queue.front();
queue.pop_front();
return true;
}
Is it possible to code something like this? I'm used to a Win32 WaitForMultipleObjects, but can't find an alternative that works for this case.
Thanks.
I've seen this related question, but it didn't really answer the problem. learning threads on linux
If I understand your problem correctly, I would probably do something like this:
bool WaitAndPop(T& value)
{
std::unique_lock<std::mutex> lk(mutex);
// Wait until the queue won't be empty OR stop is signaled
condition.wait(lk, [&] ()
{
return (stop || !(myQueue.empty()));
});
// Stop was signaled, let's return false
if (stop) { return false; }
// An item was pushed into the queue, let's pop it and return true
value = myQueue.front();
myQueue.pop_front();
return true;
}
Here, stop is a global variable like condition and myQueue (I suggest not to use queue as a variable name, since it is also the name of a Standard container adapter). The controlling thread can set stop to true (while holding a lock to mutex) and invoke notifyOne() or notifyAll() on condition.
This way, notify***() on the condition variable is invoked both when a new item is pushed into the queue and when the stop signal is being raised, meaning that a thread waking up after waiting on that condition variable will have to check for what reason it has been awaken and act accordingly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With