I have been reading about the thread-pool pattern and I can\'t seem to find the usual solution for the following problem.
I sometimes want tasks to be executed serial
I think thread pool can be effectively used in this situation. The idea is to use separate strand
object for each group of dependent tasks. You add tasks to your queue with or w/o strand
object. You use the same strand
object with dependent tasks. Your scheduler checks if the next task has a strand
and if this strand
is locked. If not - lock this strand
and run this task. If strand
is already locked - keep this task in queue until next scheduling event. When task is done unlock its strand
.
In result you need single queue, you don't need any additional threads, no complicated groups etc. strand
object can be very simple with two methods lock
and unlock
.
I often meet the same design problem, e.g. for an asynchronous network server that handles multiple simultaneous sessions. Sessions are independent (this maps them to your independent tasks and groups of dependent tasks) when tasks inside sessions are dependent (this maps session internal tasks to your dependent tasks inside a group). Using described approach I avoid explicit synchronization inside session completely. Every session has own strand
object.
And what is more, I use existing (great) implementation of this idea: Boost Asio library (C++). I just used their term strand
. Implementation is elegant: I wrap my async tasks into corresponding strand
object before scheduling them.