I have a thread pool with boost::io_service
on top. I use it for different CPU-bound tasks in whole application. For some tasks, I have to guarantee that tasks will be executed in specified order (decoding video stream). Using io_service::strand
guaranties that tasks will not be executed currently, but it has no guarantee about the order of execution. In other words, task #5 may be executed before task #4. Is there any method to solve that problem, other than scheduling next task after executing of current.

- 23,808
- 4
- 67
- 87

- 728
- 5
- 17
-
1Since you have a thread pool, define "after". 5 must start after 4 starts? After 4 ends? Must end after 4 ends? If by "after" you mean 5 must start after 4 ends, then why do you not want to schedule it at the end of 4? – uk4321 Nov 13 '13 at 06:11
-
task #5 should be executed after task #4 ends. – capone Nov 13 '13 at 06:24
-
1I do io_service.post(task#4); io_service.post(task#5); and want it executed in the posted order, as if there only one working thread. – capone Nov 13 '13 at 06:26
-
> then why do you not want to schedule it at the end of 4? The reason is - I don't want to create queue of tasks. Tasks are scheduled by event cumming from external system. – capone Nov 13 '13 at 06:31
-
1why not a task queue? And threading is pointless if you have to have an order. – uk4321 Nov 13 '13 at 16:50
-
1re-read the [strand documentation](http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/io_service__strand.html#boost_asio.reference.io_service__strand.order_of_handler_invocation). Ordering can be guaranteed. – Sam Miller Nov 13 '13 at 21:46
-
When decoding a video stream, is there intermediate output in real time? Or, is it more like a block of data that goes through a somewhat lengthy decoding process and the result is that perhaps a display method or save method is called with a pointer to the decoded block of data? – Bob Bryan Nov 14 '13 at 02:30
1 Answers
strand
provides both the guarantee of not executing completion handlers concurrently and defines the order of handler invocation. In short, completion handlers posted into a strand
are executed in the same order in which they are posted.
Therefore:
strand_.post(&task1);
strand_.post(&task2);
strand_.post(&task3);
Guarantees order of handler invocation is task1
-> task2
-> task3
. However, wrapped completion handlers for asynchronous operations are not guaranteed, as the order in which asynchronous operations are performed is unspecified. For example, the following does not provide the same guarantee:
async_read(socket1, ..., strand_.wrap(&task1));
async_read(socket2, ..., strand_.wrap(&task2));
async_read(socket3, ..., strand_.wrap(&task3));
If completion handlers must be invoked in a specified order for asynchronous operations, then either:
- Queue completion handlers and manage the order manually.
- Serialize all asynchronous operations. For example,
async_op_1
's completion handlertask1
initiatesasync_op_2
with a completion handler oftask2
.
Here is the relevant excerpt from io_service::strand
's order of handler invocation documentation:
Given:
- a strand object
s
- an object
a
meeting completion handler requirements- an object
a1
which is an arbitrary copy of a made by the implementation- an object
b
meeting completion handler requirements- an object
b1
which is an arbitrary copy of b made by the implementationif any of the following conditions are true:
s.post(a)
happens-befores.post(b)
- ...
then
asio_handler_invoke(a1, &a1)
happens-beforeasio_handler_invoke(b1, &b1)
.

- 51,153
- 9
- 112
- 169