多线程处理,同时保持部分序列

时间:2019-03-07 13:03:24

标签: c++ multithreading boost-asio

我有如下消息处理逻辑:

boost::asio::io_service ioService;
boost::thread_group threadPool;

// Initialization code.
int noOfCores = boost::thread::hardware_concurrency();
for (int i = 0 ; i < noOfCores ; i ++)
{
    threadPool.create_thread(boost::bind(&boost::asio::io_service::run, , &ioService)); 
}

稍后在套接字读取线程中,我接收消息并在绑定接收到的消息时发布处理程序函数。

ioService.post(boost::bind(MessageHandler, message));

以上行确保可以同时处理多个消息。但是,它也丢失了有时可能需要的顺序处理。实际上,由于对消息的处理时间可能会发生巨大变化,因此序列完全混乱了。

例如,假设我有A,B,C,D,E,F,G,H,I和J类型的消息。我不在乎它们按什么顺序处理,因此多线程处理是完美的。但是,我确实需要按顺序处理相同类型的消息。假设我按以下顺序收到了邮件。

C1,E1,F1,A1,B1,C2,B2,D1,D2,F2,A2,H1,H2,A3,E2,E3,F3

在这里,字母是类型,数字是它们到达的顺序。可以按任何顺序并行处理不同的消息类型,应保持该类型内的顺序。我希望在A2之前处理A1,在A3之前处理A2。每种消息类型都一样。

其中一种方法是,确保给定类型的消息始终进入同一线程。这不是很有效。如果我只有5种消息类型和32个CPU内核,那么我仍将限于5个线程。是否可以强制某个项目由特定线程处理?否则我必须为每个线程维护一个队列,处理互斥锁等。

还有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

对于每种类型的工作,您都可以使用strand作为队列。这样,您的工作可以均匀地分布在io_context线程上,并且为每种类型的工作提供顺序的工作队列,并且不需要任何互斥锁。