3

我正在为 Windows 客户端使用 Boost::ASIO 版本 1.52.0。我希望能够专用一个线程来处理从服务器接收的所有消息,然后另一个专用线程来处理所有传出到服务器的消息。我现在io_service对两个线程使用相同的对象。我担心的是,当io_service::run()调用该方法时,处理传出消息的线程可能会被安排来处理一些传入消息调用,反之亦然。所以,我的问题 - 这可能吗?如果是,那么使用第二个io_service对象会解决问题吗 - 每个线程一个?有没有更好的方法来设计这个?我试图避免对读取和写入处理程序使用多个线程。

async_reads我想确认的另一件事是 - 我已经读过如果可以同时完成2 个或更多,则应该使用锁来单线程代码。同样对于async_writes. an async如果_read 可以与 an 同时执行,是否也应该使用锁async_write,还是应该是线程安全的?

最后一个问题 -在工作线程调用run 方法之前,async_connect可以从不同的线程调用 async 方法吗?async_readasync_writeio_service

4

2 回答 2

4

您应该使用单个io_service,但是您用来调用的许多线程也io_service::run()可以为io_service. 如果这些处理程序访问共享数据结构,您将需要使用 astrand来确保独占访问。您还需要确保最多一次写入操作

此操作是根据对流async_write_some函数的零次或多次调用来实现的,称为组合操作。程序必须确保流不执行其他写入操作(例如async_write,流的async_write_some 函数,或执行写入的任何其他组合操作),直到此操作完成。

操作

此操作是根据对流async_read_some函数的零次或多次调用来实现的,称为组合操作。程序必须确保流不执行其他读取操作(例如async_read,流的async_read_some 函数,或执行读取的任何其他组合操作),直到此操作完成。

对每个插座都很出色。

不可能对所有操作使用一个,而对io_service所有async_write()操作使用另一个是不可能的,因为单个套接字由作为构造函数中的参数传入的一个套接字提供服务。io_serviceasync_read()io_service

根据我的经验,大多数 mult-io_service 设计都是由性能和延迟要求驱动的。HTTP Server 2 示例使用io_service每个 CPU对此进行了探索。

于 2013-01-24T04:23:27.723 回答
2

当您没有多个对象(即套接字)可供操作时,这是 ASIO 和 IOCP 等异步库的失败之一。就像单个 UDP 套接字向许多不同的端点发送和接收许多数据包的常见情况一样。

在这种情况下,有一个专门的线程只是在读取时阻塞并快速将数据放入队列中,而一个专门的线程在写入时阻塞比异步任何东西都要高效得多。通过这种方式,您应该能够在现代硬件上每秒获得超过 100K 的数据包。如果您可以使用 sendmmsg 或 recvmmsg 类型的函数,您可以通过避免操作系统调用开销来获得更高的数字。它们允许您将消息捆绑在一起,但最后我检查了它不在 ASIO 中,并且需要您自己的代码。

在您的示例应用程序中,因为一次只有一个 READ 或 WRITE 处理程序处于活动状态,因此两个线程应该只执行一个或另一个,因此我相信您可以避免在那里需要 strand。但是,如果您在我刚才提到的设置中使用 2 个专用的非异步线程,您的性能会好很多。

于 2016-02-23T12:27:13.673 回答