Why would we need many acceptors in the Boost.ASIO

2019-04-15 07:44发布

问题:

As known, we can use multiple acceptors in boost::asio.

boost::asio::io_service io_service_acceptors;
std::vector<boost::thread> thr_grp_acceptors;
unsigned int thread_num_acceptors = 2;

for(size_t i = 0; i < thread_num_acceptors; ++i) {
    thr_grp_acceptors.emplace_back(
        boost::bind(&boost::asio::io_service::run, &io_service_acceptors));

But is there any sense in doing io_service_acceptors more than 1?


  1. Boost.ASIO uses optimal non-blocking demultiplexing mechanism (epoll, IOCP, ...).

  2. Also even if network error will occur after epoll and before accept then accept will not been blocked, because we can set non_blocking(true);: Boost asio non-blocking IO without callbacks

http://man7.org/linux/man-pages/man2/accept.2.html

There may not always be a connection waiting after a SIGIO is delivered or select(2), poll(2), or epoll(7) return a readability event because the connection might have been removed by an asynchronous network error or another thread before accept() is called. If this happens, then the call will block waiting for the next connection to arrive. To ensure that accept() never blocks, the passed socket sockfd needs to have the O_NONBLOCK flag set (see socket(7)).

  1. The acceptor always works quickly (only accepts connections, creates a new socket, and passes it to a thread-safe queue to process them on other threads - for data exchange over these connections).

So if acceptor never blocks and the acceptor always works quickly so can one acceptor on the one CPU-Core process all the new connections?

And if they can, then why would we need many aceptors?

回答1:

The acceptor is bound to a specific endpoint.

What's more it differs with respect to protocol choice.

So, you could have several acceptors for several endpoints on several protocols.

What you seem to be after is, indeed, you can run them all on a single io_service and there would not be any need to run it on more than one thread.