boost coroutine with multi core

My tcp server is based on this boost coroutine server example.

There're lots of request per second, the server have two cores but only one is used, it never goes over than 50% cpu in task manager's performance tab, and one core is always free:

How to make boost::coroutine work with multiple cores?

I just came up a solution that add a thread_pool:

#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/spawn.hpp>
#include "thread_pool.h"
#include <iostream>

using boost::asio::ip::tcp;

class session : public std::enable_shared_from_this<session>
{
public:
  explicit session(tcp::socket socket) { }

  void go()
  {
      std::cout << "dead loop" << std::endl;
      while(1) {} // causes 100% cpu usage, just for test
  }
};

int main()
{
  try
  {

    boost::asio::io_service io_service;

    thread_pool pool(1000); // maximum 1000 threads

    boost::asio::spawn(io_service,
        [&](boost::asio::yield_context yield)
        {
          tcp::acceptor acceptor(io_service,
            tcp::endpoint(tcp::v4(), 80));

          for (;;)
          {
            boost::system::error_code ec;
            tcp::socket socket(io_service);
            acceptor.async_accept(socket, yield[ec]);
            if (!ec) {
                pool.enqueue([&] { // add this to pool
                    std::make_shared<session>(std::move(socket))->go();
                });
            }
          }
        });

    io_service.run();
  }
  catch (std::exception& e)
  {}

  return 0;
}

Now the code seems running with 100% cpu after telnet 127.0.0.1 80 twice.

But what's the common way of using coroutine with multi cores?

Answers


One thread only runs on one core, so you have to create multiple threads with separate coroutines. asio already contains some thread management support, so you mostly have to start some threads:

int main() {
  std::vector<std::thread> pool;
  try {
    boost::asio::io_service io_service;
    {
      for(auto threadCount = std::thread::hardware_concurrency();
          threadCount;--threadCount)
        pool.emplace_back([](auto io_s) {return io_s->run(); }, &io_service);
    }

    // Normal code
  } catch(std::exception &e) {}
  for(auto &thread : pool) 
    thread.join();
  return 0;
}

The important thing is to run io_service.run() on every thread. Then, after .async_accept, you can call

io_service.post(&session::go, std::make_shared<session>(std::move(socket)))

to run the session somewhere in the pool.


Need Your Help

PHP: Move file from domain to subdomain

php file subdomain move

I have a site on a domain, let's call it "mydomain.com", where people can log in.

Displaying a user profile page PHP

php mysql pdo user-profile

I'm currently in the process of making a social network. I'm am displaying all registered users with the following code.