问题
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.
回答1:
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