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.
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 handlertask1initiatesasync_op_2with 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
ameeting completion handler requirements- an object
a1which is an arbitrary copy of a made by the implementation- an object
bmeeting completion handler requirements- an object
b1which 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).
来源:https://stackoverflow.com/questions/19946555/boostio-service-how-to-guarantee-handler-execution-sequence