# Work queue with condition variable - design issue

This topic is 907 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

void ThreadFunction()
{
while( isRunningFlag ) // 'volatile bool'
{
{
// Wait on the condition variable until there are items in the queue.
}
// Pop a work item off of the queue.
}
// Handle the work item.
// Add it to the 'finished-items' queue
}
}

void Shutdown()
{
// wake up and exit the background thread
isRunningFlag = false;    //!<= must be done before signalling!
backgroundThread.Shutdown();    // ... and wait for it to finish
}


When I call Shutdown(), the application hangs waiting for the background thread to finish,

because there are no items in the 'pendingTasks' queue and the thread won't be able to exit the inner loop (when 'pendingTasks.IsEmpty()').

Then I fixed the problem by adding two checks for isRunningFlag:

// in ThreadFunction():
// added special cases just to be able to exit the loop
while( pendingTasks.IsEmpty() && isRunningFlag ) {
}
if( !isRunningFlag ) {
break;	// the queue could be empty
}


Both of them are ugly.

1) Is there any elegant/clean/'canonical' way of exiting the thread?

Is using a 'volatile bool' a good practice?

2) How can I implement priority-based task execution?

I'm thinking of organizing tasks in linked lists by their priorities, e.g. list heads are stored in a small fixed-size array [NumPriorities],

where enum { LoadPriorityHigh = 0, LoadPriorityLow = 15, NumPriorities }, and the thread will dequeue tasks from array slots starting with zero (the highest priority).

Edited by Anfaenger

##### Share on other sites

I've done something similar recently (not the priority side).

I actually made an atomic enum that tracked the state of the worker thread.

enum class WorkerThreadState : int
{
CheckingForJob,
RunningJob,
Sleeping,
Terminating,
Joined
};



I could then use the atomic compare_exchange commands to test the state to see if it was safe to change or if it had changed to a terminating state, leave it alone.

And since I had a reference to the state outside of the thread, I could query what the thread was doing at the moment.

Thread would start as CheckingForJob.  It would atomically check if the State was still CheckingForJob before checking the queue.  If it wasn't, then it was likely triggered to shutdown (Terminating).  This could have happened while processing a previous job.  Once a job was retrieved, it was set to RunningJob.  If no jobs were available, it would be set to Sleeping and wait for a condition variable to be triggered to check again.  The controlling thread would set the variable to Terminating when it was ready for it to shut down.  When set to Terminating, once whatever job it was working on was complete, it would stop the loop and set itself as ReadyToJoin.  A function outside the WorkerThread would check the vector of worker threads for threads that were ReadyToJoin and call join on them, then remove them from the vector.

Edited by Rattrap

##### Share on other sites

As far as the priority side, can you wrap the job in another structure that holds the priority as well, then just use a priority_queue ?

##### Share on other sites

Generally speaking, I've fiddled with variations of the shutdown problem and come to the conclusion that the best solution of the various ugly ones is to treat the shutdown as nothing more than another task.  So, the loop uses the first variation of "while (running)" without any other special code checks.  The owner of the thread simply implements a special "exit" task which changes the value of running.  With this, 'running' does not need to be volatile since it is modified within thread so it cleans up that little annoyance.  So, shutdown becomes:

That's about as clean as you are going to get with threads in this area.

As to the priorities item.  I will warn you that priority systems are a massive pain to get correct and you might be better off not doing that and reconsidering the issue you are trying to solve.  I gave up on prioritized tasking for a number of reasons, the first reason is simple; doing it correctly is expensive and I wanted the performance back.  Generally speaking, for game work, I look at priorities as a fix for something that breaks my preferred separation of responsibilities approach.  Let me try and explain this a bit better.

So, the basic reasons I ended up wanting priorities turned out that I had some tasks that I didn't care if they finished this frame or a frame or two in the future, but I had a consistent need of many tasks executing in the frame and I could not complete the frame until those finished.  So, after considerable trial and error, I ended up with a frame work system and thread pool working in conjunction.  Making the two items work together is a bit of a trick but generally speaking, much easier than getting priorities correct in a single solution.  Sorry I can't suggest a solution to your actual problem and only suggest a different solution all together..

##### Share on other sites

edit: never mind I think there was a mistake in my post (it was older code after all)...

Edited by Ryan_001

##### Share on other sites

I'll go with the 'dummy-task-just-to-exit-the-loop' approach.

My actual problem was creating/generating/loading/meshing voxel chunks as the player moves through the world (or growing the loaded area when a new world is created).

1. 1
2. 2
3. 3
Rutin
21
4. 4
5. 5
khawk
14

• 9
• 11
• 11
• 23
• 10
• ### Forum Statistics

• Total Topics
633653
• Total Posts
3013152
×