c++multithreadingboostboost-asioboost-coroutine

How do I make the coroutine always work in the same thread?


I want to accept connection in thread-0, then post this socket to one of other threads (1 - 31) for load-balancing, and I want then all other operations with this socket will be in the same thread, by using coroutine - to avoid inter-thread context switching.

If I use boost.coroutine1 by using boost::asio::spawn() then can the coroutine be performed alternately on different threads?

And if it can, then how do I make the call-back of coroutine always execute in the same thread from which the asynchronous operation was called, even if to io_service are binded many threads (thread-pool)?

    for (size_t i = 0; i < thread_num_executors; ++i)
        thr_grp_executors.emplace_back(
            boost::bind(&boost::asio::io_service::run, &io_service));

As known, switching between the coroutines is very fast, it takes about 10-12 ns on x86_64: http://www.boost.org/doc/libs/1_64_0/libs/coroutine/doc/html/coroutine/performance.html

But this is only true if switching of coroutines occurs within a single thread. Because thread-switching took more than 100 ns.

Then how do I make the coroutine always work in the same thread?


Solution

  • If the io_service is bound to many threads, there is no way to make the work appear on the same "physical thread" (so, logical core).

    Other than that, you can control "logical threads" by spawning the coro on a strand.

    If you must have thread-affinity, I don't think there's a better way than running the io_service on a single thread, perhaps duplicating the io_service per-thread instead.

    All of this might be subject to improvement with the more generalized Executors proposal, and I believe Chris Kohlhoff has a preview repo of that on his github. You may wish to take a look.