boost :: io_service如何保证处理程序执行顺序 [英] boost::io_service How to guarantee handler execution sequence
问题描述
我有一个线程池,顶部是boost::io_service
.我将它用于整个应用程序中不同的CPU绑定任务.对于某些任务,我必须保证任务将以指定的顺序执行(解码视频流).使用io_service::strand
可以保证当前不会执行任务,但是不能保证执行顺序.换句话说,任务#5可以在任务#4之前执行.除了在执行当前任务后安排下一个任务之外,是否有任何方法可以解决该问题.
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
提供了不同时执行完成处理程序的保证,并定义了处理程序调用的顺序.简而言之,发布到strand
的完成处理程序的执行顺序与发布它们的顺序相同.
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.
因此:
strand_.post(&task1);
strand_.post(&task2);
strand_.post(&task3);
确保处理程序调用的顺序为task1
-> task2
-> 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:
- 排队完成处理程序并手动管理订单.
- 序列化所有异步操作.例如,
async_op_1
的完成处理程序task1
用task2
的完成处理程序启动async_op_2
.
- 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
.